这些天,我已经阅读了一些关于setTimeout,setInterval的文档.我了解到
javascript是一个单独的线程,每次只执行一段代码.同时,如果有事件发生,它将被推入事件队列并阻塞直到适当的时间.我想知道,当许多事件被阻塞等待同时执行时.这些事件是否有所不同优先级,所以高优先级事件将在低优先级之前执行.或者只是一个FIFO队列.
//将运行18ms;
}; @H_301_4@在上面的代码中,setTimeout fn1将在10毫秒发生,点击事件处理程序fn2将在6毫秒,ajax回调fn3将在7毫秒.但是所有这三个函数都将被阻塞,直到for循环结束.在18ms,for循环结束,所以这些函数的调用顺序是什么.(fn1,fn2,fn3)或(fn2,fn3,fn1)
setTimeout(fn1,10); $(document).click(fn2); //will be called at 6ms; $.ajax({ajaxSuccess(fn3); //async request,it uses 7ms;})@H_301_4@for(){
//将运行18ms;
}; @H_301_4@在上面的代码中,setTimeout fn1将在10毫秒发生,点击事件处理程序fn2将在6毫秒,ajax回调fn3将在7毫秒.但是所有这三个函数都将被阻塞,直到for循环结束.在18ms,for循环结束,所以这些函数的调用顺序是什么.(fn1,fn2,fn3)或(fn2,fn3,fn1)
解决方法
为主JavaScript线程安排的工作是FIFO处理.这包括来自各种异步任务的回调,例如setTimeout和ajax完成,以及事件处理程序.唯一的例外是在主要流行环境(浏览器和节点)中,本机Promise的解析回调会跳过队列(更准确地说,进入不同的更高优先级队列),有关详细信息,请参阅
my answer here.
@H_301_4@但抛开本机承诺解决回调:
@H_301_4@but all the three functions will be blocked until the for loop finish. At 18ms,the for
loop finished,so what order does these functions will be invoked. (fn1,fn3) or (fn2,fn1)
@H_301_4@你给setTimeout的时间是近似的,因为当那个时候到来时,JavaScript UI线程可能正在忙着做其他事情(如你所知);还有(新的)规范所需的最短时间,但实施的程度因实施而异.同样,您不能保证click事件将在6ms排队,或者ajax完成将在7ms完成.
@H_301_4@如果该代码启动,并且浏览器精确地完成了10ms,并且click事件正好排队6ms,并且ajax请求正好在7ms完成,那么顺序将是:fn2(点击处理程序),fn3(ajax完成) ),fn1(setTimeout),因为这是他们排队的顺序.
@H_301_4@但请注意,这些是非常紧张的时间.在实践中,我希望回调排队的顺序实际上是随机的,因为点击的时间会有所不同,ajax的时间会有所不同等等.
@H_301_4@我认为这是一个更好的例子:
var start = +new Date(); // Queue a timed callback after 20ms setTimeout(function() { display("20ms callback"); },20); // Queue a timed callback after 30ms setTimeout(function() { display("30ms callback"); },30); // Queue a timed callback after 10ms setTimeout(function() { display("10ms callback"); },10); // Busy-wait 40ms display("Start of busy-wait"); var stop = +new Date() + 40; while (+new Date() < stop) { // Busy-wait } display("End of busy-wait"); function display(msg) { var p = document.createElement('p'); var elapsed = String(+new Date() - start); p.innerHTML = "+" + "00000".substr(elapsed.length - 5) + elapsed + ": " + msg; document.body.appendChild(p); }@H_301_4@输出的顺序是两个循环消息,后跟10ms回调,20ms回调和30ms回调,因为这是回调排队等待主JavaScript线程服务的顺序.例如:
+00001: Start of busy-wait +00041: End of busy-wait +00043: 10ms callback +00044: 20ms callback +00044: 30ms callback@H_301_4@…数字表示自脚本启动以来的毫秒数.