美文网首页
setTimeout、Promise、Async/Await 的

setTimeout、Promise、Async/Await 的

作者: 小杰66 | 来源:发表于2021-03-29 22:37 被阅读0次

    MacroTask Queue

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

    MicroTask Queue

    MicroTask Queue(微任务队列)主要包括两类:
    独立回调microTask:如Promise,其成功/失败回调函数相互独立;
    复合回调microTask:如 Object.observe, MutationObserver 和NodeJs中的 process.nextTick ,不同状态回调在同一函数体;

    MacroTask和MicroTask

    1.依次执行同步代码直至执行完毕;
    //这里JavaScript脚本执行也是一个macroTask,执行完毕后应该跳到第三步
    2.检查MacroTask 队列,若有触发的异步任务,则取第一个并调用其事件处理函数,然后跳至第三步,若没有需处理的异步任务,则直接跳至第三步;
    3.检查MicroTask队列,然后执行所有已触发的异步任务,依次执行事件处理函数,直至执行完毕,然后跳至第二步,若没有需处理的异步任务中,则直接返回第二步,依次执行后续步骤;
    4.最后返回第二步,继续检查MacroTask队列,依次执行后续步骤;
    5.如此往复,若所有异步任务处理完成,则结束;

    process.nextTick

    node中的process.nextTick方法可以在当前"执行栈"的尾部-下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。也就是说,它指定的任务总是发生在所有异步任务之前。

    console.log("start");
    let promise1 = new Promise(function (resolve) {
      console.log("promise1");
      resolve();
      console.log("promise1 end");
    }).then(function () {
      console.log("promise2");
    });
    setTimeout(function () {
      console.log("settimeout");
    });
    console.log("end");
    //start -> promise1 ->promise1 end -> end -> promise2 -> settimeout
    
    async function async1() {
      console.log("async1 start");
      await async2();
      console.log("async1 end");
    }
    async function async2() {
      console.log("async2");
    }
    
    console.log("start");
    async1();
    console.log("end");
    //async方法执行时遇到await,await后表达式会立即执行,后面的代码会放入微任务(promise)
    //start -> async1 start -> async2 -> end -> async1 end
    
    var p1 = new Promise(function (resolve, reject) {
      console.log(1);
      resolve(1);
    });
    setTimeout(function () {
      console.log(2);
    }, 0);
    p1.then(function (value) {
      console.log(3);
    });
    setTimeout(function () {
      console.log(4);
    }, 0);
    // 1->3->2->4
    
    setTimeout(function () {
      console.log("s1");
    }, 0);
    var p1 = new Promise(function (resolve, reject) {
      setTimeout(() => {
        console.log("s2");
        resolve(1);
      }, 0);
    });
    setTimeout(function () {
      console.log("s3");
    }, 0);
    for (var i = 0; i < 100; i++) {
      (function (j) {
        p1.then(function (value) {
          console.log("pt-" + j);
        });
      })(i);
    }
    // s1->s2->pt-0->...->pt-99->s3
    
    async function async1() {
      console.log("async1 start");
      await async2();
      console.log("async1 end");
    }
    async function async2() {
      console.log("async2");
    }
    console.log("script start");
    setTimeout(function () {
      console.log("setTimeout");
    }, 0);
    async1();
    new Promise(function (resolve) {
      console.log("promise1");
      resolve();
    }).then(function () {
      console.log("promise2");
    });
    console.log("script end");
    //script start -> async1 start -> async2 -> promise1 -> script end -> async1 end -> promise2 -> setTimeout
    
    console.log(1);
    setTimeout(function () {
      console.log(2);
    }, 0);
    new Promise(function (resolve) {
      console.log(3);
      resolve(Date.now());
    }).then(function () {
      console.log(4);
    });
    console.log(5);
    setTimeout(function () {
      new Promise(function (resolve) {
        console.log(6);
        resolve(Date.now());
      }).then(function () {
        console.log(7);
      });
    }, 0);
    //1 3 5 4 2 6 7
    
    console.log(1);
    var start = Date.now();
    setTimeout(function () {
      console.log(2);
    }, 0);
    setTimeout(function () {
      console.log(4, Date.now() - start);
    }, 400);
    Promise.resolve().then(function () {
      var sum = function (a, b) {
        return Number(a) + Number(b);
      };
      var res = [];
      for (var i = 0; i < 5000000; i++) {
        var a = Math.floor(Math.random() * 100);
        var b = Math.floor(Math.random() * 200);
        res.push(sum(a, b));
      }
      res = res.sort();
      console.log(3);
    });
    // 1 3 2 4
    
    function A() {
      return Promise.resolve(Date.now());
    }
    async function B() {
      console.log(3);
      let now = await A();
      console.log(4);
    }
    console.log(1);
    B();
    console.log(2);
    //1 3 2 4
    
    console.log(1);
    setTimeout(() => {
      console.log(4);
    }, 0);
    let promise = new Promise((resolve) => {
      console.log(3);
      resolve();
    })
      .then((data) => {
        console.log(100);
      })
      .then((data) => {
        console.log(200);
      });
    console.log(2);
    //1 3 2 100 200 4
    
    console.log(1);
    setTimeout(() => {
      console.log(2);
      new Promise((resolve) => {
        console.log(4);
        resolve();
      }).then(() => {
        console.log(5);
      });
    });
    new Promise((resolve) => {
      console.log(7);
      resolve();
    }).then(() => {
      console.log(8);
    });
    setTimeout(() => {
      console.log(9);
      new Promise((resolve) => {
        console.log(11);
        resolve();
      }).then(() => {
        console.log(12);
      });
    });
    //1 7 8 2 4 5 9 11 12
    
    console.log(1);
    setTimeout(() => {
      console.log(2);
      new Promise((resolve) => {
        console.log(4);
        resolve();
      }).then(() => {
        console.log(5);
      });
      process.nextTick(() => {
        console.log(3);
      });
    });
    new Promise((resolve) => {
      console.log(7);
      resolve();
    }).then(() => {
      console.log(8);
    });
    process.nextTick(() => {
      console.log(6);
    });
    // 1 7 6 8 2 4 3 5
    
    console.log(1);
    setTimeout(() => {
      console.log(2);
      new Promise((resolve) => {
        console.log(4);
        resolve();
      }).then(() => {
        console.log(5);
      });
      process.nextTick(() => {
        console.log(3);
      });
    });
    new Promise((resolve) => {
      console.log(7);
      resolve();
    }).then(() => {
      console.log(8);
    });
    process.nextTick(() => {
      console.log(6);
    });
    setTimeout(() => {
      console.log(9);
      process.nextTick(() => {
        console.log(10);
      });
      new Promise((resolve) => {
        console.log(11);
        resolve();
      }).then(() => {
        console.log(12);
      });
    });
    
    //1 7 6 8 2 4 3 5 9 11 10 12
    

    参考链接:
    https://juejin.cn/post/6844903655473152008
    http://www.ruanyifeng.com/blog/2014/10/event-loop.html

    相关文章

      网友评论

          本文标题:setTimeout、Promise、Async/Await 的

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