setTimeout、Promise和正常回调的执行顺序

325 阅读1分钟
  1. Promise产生的异步代码 在JS的引擎解析时 属于微观任务 必须保证在一个宏观任务中完成,而setTimeout等宿主API属于 宏观任务
  2. 在JS引擎的执行过程中 先将宏观任务排列 在每一个宏观任务中 再去将微观任务排列
  3. 由于先宏观在微观 所以微观任务级别的Promise会先setTimeout的宏观任务执行
//setTimeout为浏览器API 所以产生的是宏观任务 并且排在js任务之后
//setTimeout为第二序列的宏观任务
setTimeout(() => { console.log('h') }, 500)
console.log('a')
for(let i = 0; i < 100000; i++) {}
setTimeout(() => { console.log('f') }, 100)
setTimeout(() => { console.log('g') }, 200)
setTimeout(() => console.log('e'), 0)    
var r = new Promise(function(resolve, reject){
  			//第一序列的宏观任务
        console.log('b');
        resolve()
    });
		//then执行的为Promise的异步函数 为微观异步任务 所以排在第一序列宏观任务的最末
    r.then(() => console.log('d'));
		//正常执行 为第一序列的宏观任务的尾部
    console.log('c')
//输出结果为 a b c d e f g h
  1. 从上述的代码执行结果来看 执行顺序分别是:第一序列宏观任务(a、b、c)=> 第一序列微观任务(d)=> 第二序列宏观任务(setTiemout)=> 此时按顺序执行下来之后 分别是500ms后将log('h')插入第二序列微观任务中、100ms后将log('f')插入第二序列微观任务中 最终第二序列宏观任务完成后 第二序列微观任务的排序分别为 0、100、200、500ms后插入到的log的顺序打印 => 结果 a b c d e f g h