美文网首页JavaScriptJavaScript基础知识JS
[JavaScript] Macrotask Queue和Mic

[JavaScript] Macrotask Queue和Mic

作者: 何幻 | 来源:发表于2016-03-07 07:16 被阅读4881次
    setImmediate(function(){
        console.log(1);
    },0);
    setTimeout(function(){
        console.log(2);
    },0);
    new Promise(function(resolve){
        console.log(3);
        resolve();
        console.log(4);
    }).then(function(){
        console.log(5);
    });
    console.log(6);
    process.nextTick(function(){
        console.log(7);
    });
    console.log(8);
    
    结果是:3 4 6 8 7 5 2 1
    

    事件的注册顺序如下:

    setImmediate - setTimeout - promise.then - process.nextTick
    

    因此,我们得到了优先级关系如下:

    process.nextTick > promise.then > setTimeout > setImmediate
    

    至于为什么promise.then比setTimeout优先执行,原因如下:

    Promise/A+规范指出:
    Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.

    V8实现中,两个队列各包含不同的任务:

    macrotasks: script(整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering
    microtasks: process.nextTick, Promises, Object.observe, MutationObserver
    

    执行过程如下:
    JavaScript引擎首先从macrotask queue中取出第一个任务
    执行完毕后,将microtask queue中的所有任务取出,按顺序全部执行
    然后再从macrotask queue中取下一个
    执行完毕后,再次将microtask queue中的全部取出;
    循环往复,直到两个queue中的任务都取完。

    解释:
    代码开始执行时,所有这些代码在macrotask queue中,取出来执行之。
    后面遇到了setTimeout,又加入到macrotask queue中,
    然后,遇到了promise.then放入到了另一个队列microtask queue
    等整个execution context stack执行完后,
    下一步该取的是microtask queue中的任务了。
    因此promise.then的回调比setTimeout先执行。


    参考

    8.1.4 Event loops - Perform a microtask checkpoint

    相关文章

      网友评论

        本文标题:[JavaScript] Macrotask Queue和Mic

        本文链接:https://www.haomeiwen.com/subject/kqdnkttx.html