【校招VIP】[前端面试之JS]微任务和宏任务

10月23日 收藏 0 评论 0 前端开发

【校招VIP】[前端面试之JS]微任务和宏任务

转载声明:文章来源https://blog.csdn.net/qq_40695234/article/details/126141637 

1、宏任务以及微任务的分类

宏任务

setTimeoout、setInterval

微任务

process.nextTick

这个方法是nodeJS里面的方法,如果说放在html页面中的script标签块中执行,是会报错的。其中process对象是一个全局对象,具有一些可被用来获取nodejs应用程序以及运行该应用程序的用户、运行环境的各种信息的属性、方法和事件。

process.nextTick( callback )方法用于将一个函数推迟到代码中所书写的下一个同步方法执行完毕时或异步方法的事件回调函数开始执行时调用,该方法中使用一个参数,参数值是被推迟的函数。

promise的then方法

就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

2、执行顺序

虽然说都是异步任务,但是执行顺序不同的。

1、存在微任务的话,就执行所有的微任务

2、微任务都执行完之后,执行下一个宏任务

3、但不是说所有宏任务执行完毕之后,才执行微任务的。而是当前的宏任务执行完毕,然后执行所有的微任务(这一点需要注意)

3、案例

案例1

let p = Promise.resolve().then(() => {
console.log(p);
const timer2 = setTimeout(() => {
console.log('timer2')
}, 0)
});
const timer1 = setTimeout(() => {
console.log('timer1')
Promise.resolve().then(() => {
console.log('promise2')
})
}, 0)
console.log('start');

输出:

代码运行步骤:

1、遇到Promise.resolve().then作为微任务,加入到微任务队列

2、timer1是宏任务,加入到宏任务队列

3、console.log同步代码,输出`start`,主线程中同步任务执行完。

4、微任务队列中有Promise.resolve().then,输出p,因为此时p没有resolve(),以及reject()终止掉,因此会输出`pending`。

4、timer2是宏任务,加入到宏任务队列,此时宏任务队列中有timer1、timer2。

5、微任务执行结束,进入到下一轮宏任务阶段。运行timer1,输出`timer1`,Promise.resolve().then是微任务。

6、宏任务结束,运行微任务,输出`promise2`。

7、微任务运行结束。此时宏任务队列中还有timer2,因此输出`timer2`

案例2

setTimeout(()=>{
new Promise(resolve =>{
resolve();
}).then(()=>{
console.log('test');
});

console.log(4);
});

new Promise(resolve => {
resolve();
console.log(1)
}).then( () => {
console.log(3);
Promise.resolve().then(() => {
console.log('before timeout');
}).then(() => {
Promise.resolve().then(() => {
console.log('also before timeout')
})
})
})
console.log(2);

输出

代码运行步骤:

1、遇到setTimeout是宏任务,加入到宏任务队列。

2、new Promise,**在实例化的过程中所执行的代码都是同步进行的**。因此输出`1`。

3、遇到.then,加入到微任务队列

4、console.log同步任务,输出`2`。主线程执行完毕

5、微任务队列中有任务,执行,输出`3`。

6、再次遇到Promise.resolve().then,加入微任务队列,

7、Promise.resolve().then(微任务a).then(微任务b),将其依次放入微任务队列中;

8、从微任务队列中依次取出微任务:输出`before timeout`、`also before timeout`。

9、微任务队列执行完,宏任务队列中还有任务,取出执行。遇到.then,将其放入微任务队列中,遇到同步任务console,输出`4`。宏任务执行完毕。

10、微任务队列中还有数据,因此输出`test`

 案例3

若想要异步任务尽可能快的执行,那就使用process.nextTick()

根据语言规格,Promise对象的回调函数,会进入异步任务里面的”微任务“(microtask)队列。微任务队列追加在process.nextTick队列的后面。也属于本轮循环。

请看下面这个例子:

process.nextTick(()=>console.log(1))
Promise.resolve().then(()=>console.log(2))
process.nextTick(()=>console.log(3))
Promise.resolve().then(()=>console.log(4))

输出:1,3,2,4

但是如果换一种方式调用promise结果就不同了

process.nextTick(() => console.log(1))
new Promise(function (resolve) { }).then(console.log(2))
process.nextTick(() => console.log(3))
new Promise(function (resolve) { }).then(console.log(4))

输出是:2,4,1,3

因为new Promise**在实例化的过程中所执行的代码都是同步进行的**,

因此.then先加入到微任务队列中,因此先执行。

C 0条回复 评论

帖子还没人回复快来抢沙发