宏任务和微任务
01 js在栈队执行顺序
栈里面的先出栈,然后队里面的进栈,出栈(调用栈执行完了,执行队列 )
02 队列里面分为宏队列和微队列
先执行栈,再执行微队列,最后执行宏队列
都是微任务时:先执行外层,再执行内层
源代码举例:
// 开启了一个定时器
// 定时器的作用是间隔一段时间后,将函数放入到任务队列中
// setTimeout(() => {
// console.log(1)
// }, 0)
/*
Promise的执行原理
- Promise在执行,then就相当于给Promise了回调函数
当Promise的状态从pending 变为 fulfilled时,
then的回调函数会被放入到任务队列中
*/
// Promise.resolve(1).then(() => {
// console.log(2)
// })
/*
queueMicrotask() 用来向微任务队列中添加一个任务
*/
// setTimeout(() => {
// console.log(1)
// })
// Promise.resolve().then(() => {
// setTimeout(()=>{
// console.log(1)
// })
// })
Promise.resolve().then(() => {
Promise.resolve().then(()=>{
console.log(1)
})
})
queueMicrotask(() => {
console.log(2)
})
/*
// 阅读下列代码,并说出执行结果:1 7( 3 5)(2 6 4)
// 1 栈
console.log(1);
// 6 宏任务
setTimeout(() => console.log(2));
// 3 微任务
Promise.resolve().then(() => console.log(3));
// 4 微任务 ( 8 宏任务)
Promise.resolve().then(() => setTimeout(() => console.log(4)));
// 5 微任务
Promise.resolve().then(() => console.log(5));
// 7 宏任务
setTimeout(() => console.log(6));
// 2 栈
console.log(7);
*/
// 1 7 3 5 (2, 6, 4)
03 触发宏任务的方式
- script 中的代码块
- setTimeout()
- setInterval()
- setImmediate() (非标准,IE 和 Node.js 中支持)
- 注册事件
04 触发微任务的方式
- Promise
- MutationObserver
- queueMicrotask()
05 总结
JS是单线程的,它的运行时基于事件循环机制(event loop)
- 调用栈
栈
- 栈是一种数据结构,后进先出
- 调用栈中,放的是要执行的代码 - 任务队列
队列
- 队列是一种数据结构,先进先出
- 任务队列的是将要执行的代码
- 当调用栈中的代码执行完毕后,队列中的代码才会按照顺序依次进入到栈中执行
- 在JS中任务队列有两种
宏任务队列 (大部分代码都去宏任务队列中去排队)
微任务队列 (Promise的回调函数(then、catch、finally))
执行的整个流程
① 执行调用栈中的代码
② 执行微任务队列中的所有任务
③ 执行宏任务队列中的所有任务
06 同步,微任务,宏任务执行流程✨✨
整个流程:
1. 执行同步
- 比如,console.log
- new Promise(遇到.then/finally停下)
- async(遇到await阻塞,先执行外面的同步代码,执行完了再回到async函数,执行阻塞的代码)
(这里的new Promise, async只是声明)
2. 执行微任务
- 比如,.then
- await后面的阻塞代码
3. 执行宏任务
- 比如定时器
举例:
控制台运行: