宏任务和微任务
- 宏任务
- 包括 (
一整个script标签
或进入某个函数内部
)setTimeout
setinterval
setImmediate
,I/O,UI rendering (小白的我,后面三个都没用过)
- 包括 (
- 微任务
- 包括
Promise
,process.nextTick
,MutationObserver
- 包括
执行顺序 同步 > 微任务(micro) > 宏任务(macro)
console.log('我')
setTimeout(()=>{
console.log('子');
},0)
new Promise((resolve,reject) => {
console.log('是'); //这里是同步执行
resolve()
}).then(() => {
console.log('样');
})
setTimeout(()=>{
console.log('执行的');
},0)
console.log('这');
//输出---
//我
//是
//这
//样
//子
//执行的
new Promise((resolve,reject) => {
console.log('我'); //这里是同步执行
resolve()
}).then(() => {
console.log('样');
})
console.log('是')
setTimeout(()=>{
console.log('子');
},0)
setTimeout(()=>{
console.log('执行的');
},0)
console.log('这');
//输出---
//我
//是
//这
//样
//子
//执行的
- 这上边两端代码其实区别 不大就是 promise 和同步代码 的先后
下面再看一段代码
console.log('我')
fn();
setTimeout(()=>{
console.log('执');
},0)
setTimeout(()=>{
console.log('行的');
},0)
console.log('样');
async function fn(){
console.log('是');
let res = await promise()
console.log(res);
}
function promise(){
return new Promise((resolve,reject) => {
console.log('这');
resolve('子')
// console.log(123);
})
}
// 如果遇到了 await 的话 还是会执行对应的代码 ,只有遇到异步任务时,才会暂停
// 等清空执行栈里面的同步代码 才会重新恢复执行async函数剩下的内容
一下内容摘抄 掘金大佬 作者 血雪月传送门
事件循环图解
简单来一题
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
Promise.resolve()
.then(function () {
console.log('promise1')
})
.then(function () {
console.log('promise2')
})
console.log('script end')
// 输出结果:
// script start
// script end
// promise1
// promise2
// setTimeout
// 第一轮事件循环: script start script end promise1 promise2
// 第二轮事件循环: setTimeout
作者:雪月
链接:https://juejin.cn/post/6966158666030383118
来源:掘金
- 最开始从 script(整体代码) 开始第一次循环。之后全局上下文进入执行栈,
- 执行代码,打印 script start
- 接着遇到
setTimeout
,知道它是异步代码中的宏任务,把function () { console.log('setTimeout') }
放入宏任务队列 - 接着遇到
Promise.resolve().then
,知道它是异步代码中的微任务,把function () { console.log('promise1') }
放入微任务队列 - 执行代码,打印 script end
- 此时
script(整体代码)
执行完毕,弹出执行栈
,接着检查有没有微任务
, - 发现微任务队列中有微任务,把微任务队列中,第一个入队列的微任务从微任务队列取出,放入
执行栈
- 执行代码,打印 promise1, 隐式
return undefined
,遇到.then
,向微任务队列加入一个function () { console.log('promise1') }
,然后出栈; - 继续检查有没有
微任务
,发现有,放入执行栈
, - 执行代码,打印 promise2,继续检查有没有
微任务
,发现没有,本轮循环结束。 下一轮循环开始前的操作
:检查是否要重新渲染
页面, 判断是否执行requestAnimationFrame
requestIdleCallback
UI render
;结束以后- 开始下一轮循环,检查
宏任务队列
中,是否有任务,发现有function () { console.log('setTimeout') }
,放入执行栈
- 执行代码,打印 setTimeout
- 检查微任务队列,发现没有,本轮循环结束,执行
下一轮循环开始前的操作
这里推荐一个网站,帮助你理解事件循环点击链接
作者:雪月
链接:https://juejin.cn/post/6966158666030383118
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。