阅读 39

event loop、宏任务、微任务

原文地址 juejin.cn/post/684490…

一、概念

  • JavaScript是单线程的语言
  • Event Loop是javascript的执行机制
  • 宏任务:包括整体代码script,setTimeout,setInterval、setImmediate。
  • 微任务:原生Promise(有些实现的promise将then方法放到了宏任务中)、process.nextTick、Object.observe(已废弃)、 MutationObserver 记住就行了。
  • 遇到宏任务,先执行宏任务,将宏任务放入eventqueue,然后在执行微任务,将微任务放入eventqueue最骚的是,这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回掉函数,然后再从宏任务的queue上拿宏任务的回掉函数。

二、简单的例子

setTimeout(()=>{
  console.log('setTimeout1')
},0)
let p = new Promise((resolve,reject)=>{
  console.log('Promise1')
  resolve()
})
p.then(()=>{
  console.log('Promise2')    
})

复制代码

最后输出结果是Promise1,Promise2,setTimeout1

Promise参数中的Promise1是同步执行的 其次是因为Promise是microtasks(微任务),会在同步任务执行完后会去清空microtasks queues, 最后清空完微任务再去宏任务队列取值。

三、复杂的例子

Promise.resolve().then(()=>{
  console.log('Promise1')  
  setTimeout(()=>{
    console.log('setTimeout2')
  },0)
})

setTimeout(()=>{
  console.log('setTimeout1')
  Promise.resolve().then(()=>{
    console.log('Promise2')    
  })
},0)

复制代码

主线程注册Promise1为微任务、setTimeout1为宏任务-》执行微任务Promise1-》注册setTimeout2为宏任务-》执行setTimeout1-》执行微任务Promise2-》执行宏任务setTimeout2

image.png

四、终极例子

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

复制代码

答案:

1,7,6,8,2,4,3,5,9,11,10,12

文章分类
前端
文章标签