微任务的创建-queueMicrotask

1,747 阅读1分钟

一道题引发的思考

console.log('start');
setTimeout(()=>{  
  console.log('timeout');})
new Promise((res,rej)=>{   
 res()}).then(()=>{ 
  console.log('promise');})
async function asyncFun(){  
  await console.log('async 1');  
  console.log('async 2');    }
asyncFun()

答案:start async 1 promise async 2 timeout

其实只要接触过EventLoop知道宏任务跟微任务的人都知道,promise.then()属于微任务。setTimeout属于宏任务。那这题的解题就呼之欲出了。

首先,我们要接受ES6的Promise.then属于异步并且为微任务,至于为什么?这里就不多讲解。

但问题在于,promise的then是如何实现微任务的呢?我前段事件手写过Promise的代码,但那时候我实现是用的setTimtout,直到遇到这道题的时候我突然意识到我的实现是错误的。终于我在忙忙的相同的没有营养的文章中发现了一个关键的函数——queueMicrotask。我想我终于解开了疑惑。

setTimeout(()=>{   
 console.log('timeout');    })
queueMicrotask(test)
function test(){  
  console.log('test');}
new Promise((res,rej)=>{  
  res()}).then(()=>{ 
   console.log('promise');})
console.log('start');

很明显,queueMicrotask是可以将函数转换成微任务。这也就明了了Promise的resolve为什么是微任务了。

兼容性


总结

其实解开这个疑惑花了不少的时间,因为网上关于queueMicrotask的介绍少之又少。上面那道题背背书其实就可以解,但我就是想知道为什么我自己手写的Promise.then并不是在微任务了。正因为这份执念,我才能刨根到底找到了原因。正如我想表达的,刷题是为了更好的查漏补缺自己,而不是为了刷题而背书。