JavaScript 宏任务与微任务

一、什么是宏任务和微任务?

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

二、JS为什么要区分宏任务和微任务?

(1)js是单线程的,但是分同步异步
(2)微任务和宏任务皆为异步任务,它们都属于一个队列
(3)宏任务一般是:script、setTimeout、setInterval、postMessage、MessageChannel、setImmediate(Node.js 环境)
(4)微任务:Promise.then、Object.observe、MutationObserver、process.nextTick(Node.js 环境)
(5)先执行同步再执行异步,异步遇到微任务,先执行微任务,执行完后如果没有微任务,就执行下一个宏任务,如果有微任务,就按顺序一个一个执行微任务

三、宏任务、微任务有哪些?

  • 宏任务一般是:script、setTimeout、setInterval、postMessage、MessageChannel、setImmediate(Node.js 环境)
  • 微任务:Promise.then、Object.observe、MutationObserver、process.nextTick(Node.js 环境)

四、宏任务、微任务是怎么执行的?

执行顺序:先执行同步代码,异步任务放入任务队列中,当所有同步代码执行完毕后,先执行微任务在执行宏任务。

示例

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在实例化的过程中所执行的代码都是同步进行的,所以输出2
  3. Promise.then是异步微任务,将其放入微任务队列中
  4. 遇到同步任务console.log(5);输出5;主线程中同步任务执行完
  5. 从微任务队列中取出任务到主线程中,输出3、 4,微任务队列为空
  6. 从宏任务队列中取出任务到主线程中,输出1,宏任务队列为空
console.log(1)
setTimeout(function() {
    console.log(2)
}, 0)
const p = new Promise((resolve, reject) => {
    resolve(4)
})
p.then(data => {
    console.log(data)
})
console.log(3)
//1,3,4,2
  • 遇到同步任务console.log(1);输出1;
  • 遇到setTimeout 异步宏任务,放入宏任务队列中;
  • 遇到 Promise,new Promise在实例化的过程中所执行的代码都是同步进行的,但由于new Promise没有输出事件,所以接着执行遇到.then;
  • 执行.then,异步微任务,被分发到微任务Event Queue中;
  • 遇到同步任务console.log(3);输出3;
  • 主线程中同步任务执行完,从微任务队列中取出任务到主线程中,p.then 输出4,微任务执行完毕,任务队列为空;
  • 开始执行宏任务setTimeout 输出2,宏任务队列为空;

猜你喜欢

转载自blog.csdn.net/weixin_46769087/article/details/131406632