浅析setTimeout与Promise

作者: yonglei_shang | 来源:发表于2018-11-06 17:42 被阅读4次

    我们先看一到常见的前端面试题:

    var p1 = new Promise(function(resolve, reject){
        resolve(1);
    })
    setTimeout(function(){
      console.log("will be executed at the top of the next Event Loop");
    },0)
    p1.then(function(value){
      console.log("p1 fulfilled");
    })
    setTimeout(function(){
      console.log("will be executed at the bottom of the next Event Loop");
    },0)
    
    

    上例代码执行输出顺序如何?这道题也是本文创作的源泉,其答案是:

    p1 fulfilled
    will be executed at the top of the next Event Loop
    will be executed at the bottom of the next Event Loop
    
    

    异步任务



    回顾JavaScript事件循环并发模型,我们了解了setTimeout和Promise调用的都是异步任务,这一点是它们共同之处,也即都是通过任务队列进行管理/调度。那么它们有什么区别吗?下文继续介绍。

    任务队列

    前文已经介绍了任务队列的基础内容和机制,可选择查看,本文对任务队列进行拓展介绍。JavaScript通过任务队列管理所有异步任务,而任务队列还可以细分为MacroTask Queue和MicoTask Queue两类。

    MacroTask Queue

    MacroTask Queue(宏任务队列)主要包括setTimeout,setInterval, setImmediate, requestAnimationFrame, NodeJS中的`I/O等。

    MicroTask Queue

    MicroTask Queue(微任务队列)主要包括两类:

    独立回调microTask:如Promise,其成功/失败回调函数相互独立;
    复合回调microTask:如 Object.observe, MutationObserverNodeJs中的 process.nextTick ,不同状态回调在同一函数体;

    MacroTask和MicroTask

    JavaScript将异步任务分为MacroTask和MicroTask,那么它们区别何在呢?

    依次执行同步代码直至执行完毕;
    检查MacroTask 队列,若有触发的异步任务,则取第一个并调用其事件处理函数,然后跳至第三步,若没有需处理的异步任务,则直接跳至第三步;
    检查MicroTask队列,然后执行所有已触发的异步任务,依次执行事件处理函数,直至执行完毕,然后跳至第二步,若没有需处理的异步任务中,则直接返回第二步,依次执行后续步骤;
    最后返回第二步,继续检查MacroTask队列,依次执行后续步骤;
    如此往复,若所有异步任务处理完成,则结束;

    链接:https://juejin.im/post/5b7057b251882561381e69bf

    相关文章

      网友评论

        本文标题:浅析setTimeout与Promise

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