JavaScript事件循环
JavaScript中任务可以分为同步任务和异步任务
异步任务又分为宏认为和微任务
ES5之后,JavaScript引入了Promise,现在不需要浏览器,JavaScript引擎也能够发起异步任务了
宏任务是由宿主发起的(浏览器、Node)
微任务是由JavaScript引擎发起的
- Promise本身同步,then/catch的回调函数是异步的
宏任务、微任务执行过程
代码可能有三种:
-
同步代码 ,由
Js执行栈/回调栈执行 -
微任务的异步代码,由
Js引擎执行,会优先执行process.nextTick #NodePromist.then().catch()Async/AwaitObject.observe- ...
-
宏任务 由宿主环境执行
script代码块setTimeout/ setInterval定时器setImmediate定时器I/O
宏任务、微任务-执行过程顺序
- 同步代码
- 为任务的异步代码(Promise等)
- 宏任务的异步代码(定时器等)
执行栈、宏任务队列、微任务队列
完整的执行过程:
- 首先执行执行栈里的同步代码,执行完毕之后,去微任务队列中检查是否有任务,
- 有的话根据队列的特性
先进先出,拿到微任务队列里的任务,通过事件循环推到执行栈中执行,重复执行此步骤到微任务队列结束 - 最后去宏任务队列,也是
先进先出,通过事件循环推到执行栈中执行,但是执行完每一个宏任务的时候,会去检查微任务队列,如果有新添加进来的微任务队列就优先执行第二步,直到微任务队列清空后才会执行下一个微任务
console.log(1); //同步任务
setTimeout(function(){ //宏任务
console.log(2);
},200);
const task = new Promise((resolve,reject)=>{
console.log(3); //同步任务
resolve(4); //
console.log(5); //同步任务
});
task.then(data=>{ //异步任务中的微任务
console.log(data);
})
console.log(6); //同步任务
/** output
1
3
5
6
4
2
*/
最后补充一点,Promise中的reject和resolve是不能终止代码执行,需要自己return,所以5会被打印出来
有错误的地方欢迎大佬指正!