宏任务和微任务

前端

区分:

执行同步和立即执行任务:

console.log(),new Promise()

宏任务:

1. script (可以理解为外层同步代码)2. setTimeout/setInterval3. UI rendering/UI事件4. postMessage,MessageChannel5. setImmediate,I/O(Node.js)

微任务:

1. Promise(只有then()才是异步微任务,new Promise()是同步任务)2.process.nextTick(Node.js) 3. Object.observe(已废弃;Proxy 对象替代)4. MutaionObserver

执行顺序:

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

简单理解的执行顺序:

1.先运行同步和立即执行任务

2.再运行微任务

3.再运行宏任务

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.代码先遇到setTimeout,为异步宏任务,将里面代码放到红队列中

2.遇到new Promise,为同步代码,那么执行输出2,再遇到.then().then(),为异步微任务,放入异步微任务队列中。

3.遇到console.log(),为同步代码,那么执行输出5

直到这里,所有代码块的同步代码都执行完成,接下来执行微任务队列

4.在以上步骤中,只遇到.then().then()是微任务,所以执行输出3,4

直到这里,所有代码块的异步微任务执行完成,接下来执行宏任务队列

5.只剩setTimeout宏任务没有执行,所以输出1

async  function  async1 ()  {
    console.log('async1 start');
    await  async2();
    console.log('async1 end')
}
async  function  async2 ()  {
    console.log('async2')
}
console.log('script start');
setTimeout(function ()  {
    console.log('setTimeout')
},  0);
async1();
new  Promise(function (resolve)  {
    console.log('promise1');
    resolve()
}).then(function ()  {
    console.log('promise2')
});
console.log('script end')

解析:1.代码从上往下执行,async1,和async1没有被调用,先不看

2.遇到console.log()同步代码,直接输出script start

3.遇到setTimeout,宏任务,将里面加入宏任务队列

4.async1()被调用, 输出async1 start,然后再调用async2(),输出async2,再遇到console.log('async1 end'),这里是微任务,加入队列(

 process.nextTick (node中实现的api,把当前任务放到主栈最后执行,当主栈执行完,先执行nextTick,再到等待队列中找)

从async2执行完后 会返回async1中执行剩余代码 这个过程就是process.nextTick() ,算微任务)

5.遇到new Promise同步代码,输出promise1,.then()将里面代码加入微任务队列

6.遇到console.log()同步代码,输出script end

直到这里,所有代码块的同步代码都执行完成,接下来执行微任务队列

7.  第4步将console.log('async end')的代码加入了微任务,所以输出async1 end

8. 第5步。.then()代码加入了微任务,所以输出promise2

直到这里,所有代码块的异步微任务执行完成,接下来执行宏任务队列

9. 回到第三部,执行setTimeout,输出setTimeout

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})
// 1 7 6 8 2 4 3 5 9 11 10 12

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值