Javascript事件循环机制:宏任务/微任务,同步任务和异步任务

212 阅读2分钟

javascript 是一种单线程语言,同一时刻只能运行一个线程

执行顺序:先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕 即:同步任务->异步微任务->异步宏任务(由先到后)

宏任务(macrotask)微任务(microtask)
谁发起的宿主(Node、浏览器)JS引擎
具体事件1. script (可以理解为外层同步代码)
2. setTimeout/setInterval
3. UI rendering/UI事件
4. postMessage,MessageChannel
5. setImmediate,I/O(Node.js)
1. Promise
2. MutaionObserver
3. Object.observe(已废弃;Proxy 对象替代)
4. process.nextTick(Node.js)
谁先运行后运行先运行
会触发新一轮Tick吗不会

示例一:

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('asnyc1 end');
}
async function async2() {
    console.log('async2');
}
console.log('script start');
setTimeout(() => {
    console.log('setTimeOut');
}, 0);
async1();
new Promise(function (reslove) {
    console.log('promise1');
    reslove();
}).then(function () {
    console.log('promise2');
})
console.log('script end');
// 答案
1、script start
2、async1 start
3、async2
4、promise1
5、script end
6、asnyc1 end
7、promise2
8、setTimeOut

image.png

示例二:

setTimeout(function(){
    console.log('1');
});
new Promise(function(resolve){
    console.log('2');
    resolve();
}).then(function(){
    console.log('3');
}).then(function(){
console.log('4')
});
console.log('5');
// 2 5 3 4 1
// 1.遇到setTimout,异步宏任务,放入宏任务队列中
// 2.遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出2
// 3.而Promise.then中注册的回调才是异步执行的,将其放入微任务队列中
// 4.遇到同步任务console.log(‘5’);输出5;主线程中同步任务执行完
// 5.从微任务队列中取出任务到主线程中,输出3、 4,微任务队列为空
// 6.从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空

参考

  1. 我终于搞懂了async/await、promise和setTimeout的执行顺序 - 掘金
  2. 什么是宏任务、微任务?宏任务、微任务有哪些?又是怎么执行的?什么是宏任务和微任务F N Janine的博客-CSDN博客