宏任务和微任务

原文链接:https://blog.csdn.net/NancyFyn/article/details/118407548

1.宏任务和微任务是什么?

js是一种单线程语言,简单的说就是只有一条通道,在任务多的情况下,就会出现拥挤的情况,这种情况下就产生’多线程’,但是这种“多线程”是通过单线程模仿的,也就是假的,那么也就产生了同步任务和异步任务

在这里插入图片描述

2.宏任务和微任务有哪些

宏任务:

  1. script (可以理解为外层同步代码)
  2. setTimeout/setInterval
  3. UI rendering/UI事件
  4. postMessage,MessageChannel
  5. setImmediate,I/O(Node.js)
    微任务:
  6. Promise
  7. process.nextTick(Node.js)
  8. Object.observe(已废弃;Proxy 对象替代)
  9. MutaionObserver

3. 宏任务和微任务是怎么执行的?*****

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

这里容易产生一个错误的认识:就是微任务先于宏任务执行。实际上是先执行同步任务,异步任务有宏任务和微任务两种,先将宏任务添加到宏任务队列中,将宏任务里面的微任务添加到微任务队列中。所有同步执行完之后执行异步,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行。之后就一直循环
在这里插入图片描述

4.案例

setTimeout(function(){  // 异步宏任务5
	console.log('1');
});
new Promise(function(resolve){ // 同步任务	1	    
	console.log('2');
	resolve();
}).then(function(){		    // 异步微任务3
	console.log('3'); 
}).then(function(){ // 异步微任务4
console.log('4')
}); 		
console.log('5');  // 同步任务2
// 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,宏任务队列为空

例2:

setTimeout(()=>{ // 异步宏任务
  new Promise(resolve =>{  // 同步6
  	resolve();
  }).then(()=>{ // 异步微任务8
  	console.log('test');
  });

  console.log(4); // 同步7
});

new Promise(resolve => { // 同步1
  resolve();
  console.log(1)
}).then( () => { // 异步微任务 3
  console.log(3);
  Promise.resolve().then(() => { // 异步微任务4
    console.log('before timeout');
  }).then(() => {  // 异步微任务
    Promise.resolve().then(() => {  // 异步微任务5
      console.log('also before timeout')
    })
  })
}) 
console.log(2); //同步2

/// 1 2 3 before timeout also before timeout  4 test

分析:
1.遇到setTimeout,异步宏任务,将() => {console.log(4)}放入宏任务队列中;
2.遇到new Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,所以输出1;
3.而Promise.then中注册的回调才是异步执行的,将其放入微任务队列中
4.遇到同步任务console.log(2),输出2;主线程中同步任务执行完
5.从微任务队列中取出任务到主线程中,输出3,此微任务中又有微任务,Promise.resolve().then(微任务a).then(微任务b),将其依次放入微任务队列中;
6.从微任务队列中取出任务a到主线程中,输出 before timeout;
7.从微任务队列中取出任务b到主线程中,任务b又注册了一个微任务c,放入微任务队列中;
8.从微任务队列中取出任务c到主线程中,输出 also before timeout;微任务队列为空
9.从宏任务队列中取出任务到主线程,此任务中注册了一个微任务d,将其放入微任务队列中,接下来遇到输出4,宏任务队列为空
10.从微任务队列中取出任务d到主线程 ,输出test,微任务队列为空
案例3:

console.log('1');  // 同步   1

setTimeout(function() { // 异步宏任务
    console.log('2');   // 同步  5
    process.nextTick(function() { // 异步微任务 7
        console.log('3');
    })
    new Promise(function(resolve) {// 同步  6
        console.log('4'); 
        resolve();
    }).then(function() {// 异步微任务 8
        console.log('5')
    })
})
process.nextTick(function() {  // 异步微任务 3
    console.log('6');
})
new Promise(function(resolve) {  // 同步  2
    console.log('7');
    resolve();
}).then(function() { // 异步微任务  4
    console.log('8')
})

setTimeout(function() {  // 异步宏任务
    console.log('9'); // 同步  9
    process.nextTick(function() {// 异步微任务11
        console.log('10');
    })
    new Promise(function(resolve) {// 同步10 
        console.log('11');
        resolve();
    }).then(function() {// 异步微任务 12
        console.log('12')
    })
})

// 1  7  6  8  2  4  3  5  9  11  10  12
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值