JavaScript中的异步队列

2021-06-23  本文已影响0人  Spidd

而在JavaScript中有两种异步宏任务macro-task和微任务micro-task.

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

常见的异步代码实现
macro-task: script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering

micro-task: process.nextTick, Promises(原生 Promise), Object.observe(api已废弃), MutationObserver

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function executor(resolve) {
  console.log(2);
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve();
  }
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);
// 2 3 5 4 1
  1. 第一次整体代码进入macro-task。micro-task为空。
  2. macro-task执行整体代码,setTimeout加入下一次的macro-task。Promise执行打出2 3,then加入micro-task, 最后打出5。
  3. micro-task执行then被执行所以打出4。
  4. 重新执行macro-task所以打出1

Promise执行流程

  1. new Promise(func:(resolve, reject)=> void 0), 这里的func方法被同步执行。
  2. Promise 会有三种状态PENDING(执行),FULFILLED(执行成功),REJECTED(执行失败)。
  3. 在resolve,reject均未调用且未发生异常时状态为PENDING。
  4. resolve调用为FULFILLED,reject调用或者发生异常为REJECTED。
  5. 在给Promise实例调用then(callFulfilled, callRejected)来设置回调,状态不为PENDING时会根据状态调用callFulfilled和callRejected。
  6. then需要返回一个新的Promise实例.
  7. 状态为PENDING则会把callFulfilled和callRejected放入当前Promise实例的回调队列中,队列还会存储新的Promise实例。
  8. 在状态改变为FULFILLED或REJECTED时会回调当前Promise实例的队列。
上一篇 下一篇

猜你喜欢

热点阅读