关于浏览器的事件队列

 1 setTimeout(()=> console.log("a"),0);//定时器 回调
 2 var p=new Promise(resolve=>{
 3   //直接写在new Promise中的代码属于主程序,会立刻执行
 4   console.log("b");//主程序  立刻执行
 5   setTimeout(()=>console.log("f"),0);//定时器  回调
 6   resolve();//自动调用.then()中的代码
 7 });
 8 p.then(()=>console.log("c"));//微任务  回调
 9 p.then(()=>console.log("d"));//微任务  回调
10 console.log("e");//主程序

例如setTimeout(()=>{...}),setInterval(()=>{...}),xhr.send()等语句都是异步调用语句,它们会创建对象,但暂不执行,(当定时器等待时间结束时,回调函数会自动执行,当Xhr.onreadystatechange(){...}相应结果回来时会自动执行,这些异步回调函数执行时都不能进入主程序执行,会先进入任务队列等待),当主程序执行完后,事件循环会将事件队列里的回调函数放到主程序执行,会按顺序执行,先进队列的回调函数先出队列。

但有一种特殊对象promise会直接放到主程序执行(直接写在new promise里的代码属于主程序会立刻执行,但写在里面的异步代码还是会异步执行),promise的then不会放到异步对象里执行,会放到微任务中,微任务是比一般函数更小的函数,事件循环会先碰见微任务,所以微任务会比ajax,定时器优先执行,resolve()会启动.then中的代码,虽然会立刻调用还是会排在主程序后,总结起来执行顺序为主程序、微任务、异步任务。

所以上面代码输出结果为

b e c d a f

 还有一种更特殊的回调.nextTick,它也会放入微任务中执行,但又比.then优先级高,所以会比.then提前执行

process.nextTick(function(){console.log(7)});
new Promise(function(resolve){
  console.log(3);//主程序
  resolve();
  console.log(4);//主程序
}).then(function(){
  console.log(5);
})
process.nextTick(function(){
  console.log(8);
})
//输出结果 3 4 7 8 5
原文地址:https://www.cnblogs.com/zhiqiuyiye/p/12747659.html