美文网首页
JS异步--setTimeout及Promise的执行过程

JS异步--setTimeout及Promise的执行过程

作者: 秘果_li | 来源:发表于2019-03-07 14:17 被阅读0次

    Promise

    Promise新建后会立即执行,then方法指定的回调函数在当前脚本的所有同步任务执行完时执行

    setTimeout

      setTimeout(function() {
              console.log('B');
         }, 0);
    

    第二个参数设为0只是把函数放入异步队列,浏览器执行完同步队列中的任务才去执行异步队列中的任务,所以A,B处于异步队列中最后才被执行

    关于异步任务队列

    Macrotasks(task queue)和Microtasks 都属于异步任务中的一种,他们分别有如下API:
    macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
    microtasks: process.nextTick, Promise, MutationObserver

    Promise的函数代码的异步任务会优先setTimeout的延时为0的任务先执行。因为任务队列分为 macrotasks 和 microtasks, 而promise中的then方法的函数会被推入到microtasks队列中,而setTimeout函数会被推入到macrotasks

    事件循环的执行过程

    开始 -> 取macrotasks的一个任务(task)执行-> 取microtask全部任务依次执行 -> 取macrotasks下一个任务执行 -> 再次取出microtask全部任务执行 -> ... 这样循环往复

    注:macrotask的前一个task的回调函数会在下一个task开头执行,即在前一趟的microtask之后执行

    setTimeout(() => {
        console.log('A');
    }, 0);
    
    
    var obj = {
    func: function() {
         setTimeout(function() {
              console.log('B');
         }, 0);
    
         return new Promise(function(resolve) {
              console.log('C');
              resolve();
             });
        }
    };
    
    obj.func().then(function() {
        console.log('D');
    });
    
    console.log('E');
    //输出结果如下
    //C
    //E
    //D
    //A
    //B
    

    1、首先 setTimeout A 被加入到事件队列中 ==> 此时macrotasks中有[‘A’];

    2、obj.func()执行时,setTimeout B 被加入到事件队列中 ==> 此时macrotasks中有[‘A’,‘B’];

    3、接着return一个Promise对象,Promise 新建后立即执行console.log(‘C’); 控制台首次打印‘C’;

    4、然后,then方法指定的回调函数,被加入到microtasks队列,将在当前脚本所有同步任务执行完才会执行。 ==> 此时microtasks中有[‘D’];

    5、然后继续执行当前脚本的同步任务,故控制台第二次输出‘E’;

    6、此时所有同步任务执行完毕,如上所述先检查microtasks队列完成其中所有任务,故控制台第三次输出‘D’;

    7、最后再执行macrotask的任务,并且按照入队列的时间顺序,控制台第四次输出‘A’,控制台第五次输出‘B’。

    解释来源:https://www.qdskill.com/javascript/8429.html

    相关文章

      网友评论

          本文标题:JS异步--setTimeout及Promise的执行过程

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