JavaScript中的微任务与宏任务解析

124 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

前言

js中的执行流程顺序是单向的,在运行代码执行工作的时候,是一项一项来进行的,不能同时进行工作,所以会产生相应的队列,当前运行的任务会放到主线程中,其他任务都会堆积到队列完成,当主线程的任务运行完成后,会从队列提取一个任务继续执行,以此类推

一句话概括:js执行任务时,看队列中是否有堆积任务,如果有则继续执行,没有则停止

队列中的任务

会有一些任务放到队列中,定时器setIntvalDom渲染、各种事件等,注意~事件触发后,才会把当前的任务放到队列中

setTimeout(() => {
    console.log('延迟调用');
}, 0);
console.log('正常执行')

当代码从上忘下执行的时候,首先会把正常调用部分代码放到主线程当中立刻执行,之后的延迟调用方法会放到队任务列中,等待主线程任务完成后执行

虽然从视觉上看是从上忘下执行,但顺序正好颠倒

微任务

根据Promise的顺序来看,它是一定要得到一个结果才会返回,那如果把它放到延迟调用下面,执行的顺序是什么样子?

setTimeout(() => {
    console.log('延迟调用');
}, 0);

Promise.resolve().then(()=>{
    console.log('Promise调用');
})

console.log('正常执行')

思路:当执行后首先还是打印正常执行,随后把其他的两个任务放到队列中,只是把Promise放到微任务中,延迟调用放到宏任务队列中

现在已分成三部分:主线程、微任务队列、宏任务队列

优先级

这三个任务的优先级最高的是微任务队列,其次是宏任务队列,在以上代码中的Promose它属于在微任务队列当中,它的优先级高于宏任务。

graph LR 
A[主线程]
A --> B[微任务] 
B --> E[宏任务]

异步任务

首先定时器是异步任务,所以它会放到宏任务队列中,一直等待调用,需要等到同步任务执行完成后才能执行异步任务

graph LR 
A[定时器]
A --> B[定时器模块] 
B --> C[微任务]
C --> D[主线程]

在系统中有定时器模块,当定时器启动后会启动该模块同时会把第一次任务放到该模块中,当主线程任务完成后,会自动把模块内的任务推到宏任务队列中,同时微任务队列中的任务推到主线程当中