繁体   English   中英

棘手的setTimeout序列

[英]tricky setTimeout sequence

setTimeout调用集,间隔为0、1、2、3。

 function f() { setTimeout(function a() {console.log(10);}, 3); setTimeout(function b() {console.log(20);}, 2); setTimeout(function c() {console.log(30);}, 1); setTimeout(function d() {console.log(40);}, 0); } f(); 

输出:(来自chrome。希望其他浏览器也一样)

三十

40

20

10

有人可以清楚地解释为什么订购不是30、40、10、20吗? 据说浏览器至少维持10毫秒或(规定)4毫秒的间隔。 如果是这样,请使用时间量度或解释该行为的便利方式来验证输出。 为了了解这种语言的强大功能,我错过了什么细节?

编辑:

我知道这些功能是异步的。 我已经读过约翰·雷西格(John Resig)的博客几次。 而且我知道setTimeout的回调不能保证在指定的时间间隔执行。

更准确地说,我希望能有一个可以从执行队列,事件循环,调用堆栈和计时器的角度解释行为的解释。

为了了解计时器在内部的工作方式,有一个重要的概念需要探讨:不能保证计时器的延迟。 由于浏览器中的所有JavaScript都在单线程上执行,因此异步事件(例如鼠标单击和计时器)仅在执行中存在空缺时才运行。

请参阅了解更多详情

正如@Jebin在对OP的评论中指出的那样,您在这里遇到了竞争状况。

规格如下: https : //html.spec.whatwg.org/multipage/webappapis.html#dom-windowtimers-settimeout

步骤13是我们等待的地方,等待可能在脚本当前正在执行时发生。 请参阅http://jsbin.com/faguli/edit?js,console-在此示例中,由于脚本花费很长时间才能到达下一个setTimeout ,因此首先记录“ 10”。

猜测,在Chrome中,第3个setTimeout的任务在JS管理对setTimeout的第4个调用之前排队。

因此,尽管给出了不同的答案,但在这种情况下,Chrome和Firefox都符合规范。

确定性的一种方法是将setTimeout调用作为微任务的一部分处理,然后从那里启动计时器,但是setTimeout是olllllld API,因此此处的更改可能会中断网络。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM