宏任务、微任务理解

1. 什么是宏任务 微任务

js 是一种单线程语言 简单来说 只有一条通道 在任务多的情况下 就会出现拥挤的情况 这种情况就产生了 ‘多线程’ 但是这种 ‘多线程’ 是通过单线程模仿的 也就是假的 那么就产生了 同步、异步任务。

2.JS 为什么要区分 宏任务、微任务

1 js是单线程的 但分同步异步
2 宏任务、微任务皆为 异步任务 它们都属于一个队列

3. 宏任务、微任务 有哪些

宏任务 script、setTimeout、setInterval、postMessage、MessageChannel、setImmediate
微任务 Promise.then、Object.observe、MutationObserver、process.nextTick

4. 宏任务、微任务 怎么执行的

先执行同步代码
遇到 异步宏任务 则将 异步宏任务 放入 宏任务队列中
遇到 异步微任务 则将 异步微任务 放入 微任务队列中
当所有同步代码执行完毕后
再将 异步微任务 从队列中调入 主线程执行
微任务执行完毕后
再将 异步宏任务 从队列中调入 主线程执行
一直循环 直至 所有任务执行完毕

5. 案例

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. 遇到 setTimeout 异步宏任务 放入宏任务队列中
  2. 遇到 new Promise new Promise 在实例化时所执行的代码是同步 所以输出2
  3. Promise then 异步微任务 放入微任务队列中
  4. 遇到同步任务 输出5 主线程中同步任务执行完
  5. 将 异步微任务 从队列中调入 主线程执行 输出3 4 微任务队列为空
  6. 将 异步宏任务 从队列中调入 主线程执行 输出1 宏任务队列为空
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, 2, 3, before timeout, also before timeout, 4, test
  1. 遇到 setTimeout 异步宏任务 放入宏任务队列中
  2. 遇到 new Promse new Promse 在实例化的时候 所执行的代码是同步 所以输出1
  3. 而 Promise.then 异步微任务 放入微任务队列中
  4. 遇到同步任务 输出2 主线程中同步任务执行完
  5. 将 异步微任务 从队列中调入 主线程执行 输出3
    此微任务中 又有微任务 Promise.resolve().then(微任务A).then(微任务B) 将其依次放入微任务队列中
  6. 从微任务队列中 取出 微任务A 放入 主线程中 输出 before timeout
  7. 从微任务队列中 取出 微任务B 放入 主线程中 微任务B 又有 微任务C 放入微任务队列中
  8. 从微任务队列中 取出 微任务C 放入 主线程中 输出 also before timeout 微任务队列为空
  9. 从宏任务队列中 取出 宏任务 放入 主线程中 此任务 有一个微任务D 放入微任务队列中 接下来输出4 宏任务队列为空
  10. 从微任务队列中 取出 微任务D 放入 主线程中 输出 test 微任务队列为空
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
  1. 遇到同步任务 输出 1
  2. 遇到 setTimeout 异步宏任务 放入宏任务队列中
  3. 遇到 Promise new Promise 在实例化的时候所执行的代码是同步 但由于 new Promse 没有输出事件 所以接着执行 遇到 .then
  4. 执行 .then 异步微任务 放入 微任务队列中
  5. 遇到同步任务 输出3 主线程中同步任务执行完
  6. 从 微任务队列中 取出 微任务 放入 主线程中 输出 4 主线程中微任务执行完
  7. 从 宏任务队列中 取出 宏任务 放入 主线程中 输出 2 主线程中宏任务执行完
console.log(1)
setTimeout(function() {
    console.log(2)
    new Promise(function(resolve) {
        console.log(3)
        resolve()
    }).then(function() {
        console.log(4)
    })
})

new Promise(function(resolve) {
    console.log(5)
    resolve()
}).then(function() {
    console.log(6)
})

setTimeout(function() {
    console.log(7)
    new Promise(function(resolve) {
        console.log(8)
        resolve()
    }).then(function() {
        console.log(9)
    })
})
console.log(10)
// 1, 5, 10, 6, 2, 3, 4, 7, 8, 9
  1. 遇到同步任务 输出1
  2. 遇到 setTimeout 异步宏任务 放入宏任务队列中
  3. 遇到 Promise new Promise 在实例化的时候所执行的代码是同步 所以输出5 所以接着执行 遇到 .then
  4. 执行 .then 异步微任务 放入 微任务队列 中
  5. 遇到 setTimeout 异步宏任务 放入 宏任务队列中
  6. 遇到同步任务 输出10 主线程中同步任务执行完
  7. 从 微任务队列中 取出 微任务 放入 主线程中 输出 6 主线程中微任务执行完
  8. 从 宏任务队列中 取出 宏任务 放入 主线程中 执行第一个 输出 2 3 4
  9. 再执行第二个 setTimeout 输出 7 8 9 主线程中宏任务执行完
new Promise((resolve, reject) => {
    resolve(1)
    new Promise((resolve, reject) => {
        resolve(2)
    }).then(data => {
        console.log(data)
    })
}).then(data => {
    console.log(data)
})
console.log(3)
// 3, 2, 1
  1. 遇到 Promise new Promise 在实例化的时候所执行的代码是同步 但由于 没有输出事件
    所以接着往下执行 遇到 new Promse 没有输出事件 再接着往下执行 遇到 .then 异步微任务 放入微任务队列中
  2. 再接着 .then 异步微任务 放入微任务队列中
  3. 遇到同步任务 输出 3 主线程中同步任务执行完
  4. 从微任务队列中 取出 微任务 放入 主线程 中 输出 2 3 主线程中微任务执行完 任务队列为空

总结

先同步后异步
异步 包含 宏任务 微任务
异步 遇到 微任务 先执行微任务 执行完后 如果没有微任务 就执行下一个宏任务

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值