事件循环:Promise与宏任务,微任务

宏任务与微任务

宏任务:script,setTimeout,setInterval,MessageChannel,I/O(文件,网络)相关API,DOM事件监听,setImmediate(Node.js)。

微任务:process.nextTick(Node.js)MutationObserver(浏览器),Promise.prototype.then()/catch()/finally()。

requestAnimationFrame是宏任务还是微任务?

有4种不同的情况:
宏任务里面新建宏任务:加入宏任务的队列中
运行宏任务时新建微任务:加入微任务的队列中
运行微任务时新建宏任务:加入宏任务的队列中
运行微任务时新建了微任务:新创建的微任务也会马上加入微任务队列,再下次宏任务之前一定会执行。

Promise与async函数

Promise语句属性微任务,也就是可以在一次事件循环中执行多个。直到微任务所在栈为空。但是Promise的构造函数是同步任务,

new Promise((resolve) => { … }).then(() => { … }) 在.then函数之前的部分都是同步任务。

面试中还常常出现async函数,本质上还是Promise的变种。在async函数中await语句之前,都是同步的(包括await语句),await语句之后的语句都属于await语句返回的Promise中的.then函数的回调中要执行的。有多个await语句同理等于多层Promise嵌套

setTimeout函数使用setTimeout(fn, 0)时,并不是马上执行,因为是宏任务,所以,需要等同步任务完成之后,才能运行。最小间隔时间为4毫秒

一个简单的例子

使用 setTimeout和Promise.then和async/await函数当例子看看。

setTimeout(() => {
    
    
  console.log('st1')
  Promise.resolve().then(() => {
    
     // 宏任务中新建微任务
    console.log("pr2")
  })
}, 0)
new Promise((resolve) => {
    
     // 新建Promise代码为同步执行
  setTimeout(() => {
    
    
    console.log('st2')
  })
  resolve()
}).then(() => {
    
    
  console.log("pr1")
  Promise.resolve().then(() => {
    
     // 微任务中新建微任务
    console.log("pr3")
  })
  setTimeout(() => {
    
     // 微任务中新建宏任务
    console.log('st3')
  })
})
console.log("st0")

上面这个例子的结果是:

st0
pr1
pr3
st1
pr2
st2
st3

参考资源:

我以为我很懂Promise,直到我开始实现Promise/A+规范

JavaScript 运行机制详解:再谈Event Loop

在阮一峰的博客中,使用执行栈和事件队列来描述微任务和宏任务。这两者的概念应该是等价的。

猜你喜欢

转载自blog.csdn.net/cuipp0509/article/details/117464061