小编给大家分享一下承诺比setTimeout()快的原因有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
<强>为什么承诺比setTimeout()快? 强>
1。实验
我们来做个实验。哪个执行得更快:立即解决的承诺还是立即<代码> setTimeout> 代码(也就毫是0秒的setTimeout) ?
Promise.resolve(1),然后(function 解决(),{ console.log才能(& # 39;解决! & # 39;); }); setTimeout (function 超时(),{ console.log才能(& # 39;Timed ! & # 39;); },,0);//,& # 39;解决! & # 39;//,& # 39;Timed  ! & # 39;
<代码> promise.resolve(1) 代码>是一个静态函数,它返回一个立即解析的<代码> 代码>承诺。<代码> setTimeout(回调,0)代码>以<代码> 0毫秒> 代码的延迟执行回调函数。
我们可以看到先打印<代码> & # 39;解决! & # 39;> 代码,再打印<代码>超时完成!> 代码,立即解决的承诺比立即<代码> setTimeout> 代码更快。
是因为<代码> Promise.resolve(真)(…)代码>在<代码> setTimeout (…,0)代码>之前被调用了,所以承诺过程会更快吗?公平的问题。
所以,我们稍微更改一下实验条件,然后先调用<代码> setTimeout (…,0)代码>:
setTimeout (function 超时(),{ console.log才能(& # 39;Timed ! & # 39;); },,0); Promise.resolve (1) (function 解决(),{ console.log才能(& # 39;解决! & # 39;); });//,& # 39;解决! & # 39;//,& # 39;Timed  ! & # 39;
<代码> setTimeout (…,0)代码>在<代码> Promise.resolve(真)(…)代码>之前被调用。但,还是先打印<代码>解决! 代码>在打印<代码> & # 39;超时! & # 39;代码>。
这是为啥呢?
2。事件循环
与异步JS相关的问题可以通过研究事件循环来回答。我们回顾一下异步JS工作方式的主要组成部分。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img - lt9zvhtf - 1611275604640) (/img/bVcMQaI)]
<强>调用堆栈强>是一个后进先出(后进先出)结构,它存储在代码执行期间创建的执行上下文。简单地说,调用堆栈执行这些函数。
Web api是异步操作(取回请求,承诺,计时器)及其回调等待完成的地方。
* *任务队列(任务队列)<强>是一个强> FIFO(先进先出)* *结构,它保存准备执行的异步操作的回调,例如,超时的<代码> setTimeout() 代码>的回调函数或准备执行的单击按钮事件处理程序都在任务队列中排队。
* *作业队列(作业队列)* *是一个FIFO(先入先出)结构,它保存准备执行的<代码> 代码>承诺的回调,例如,已完成的承诺的<代码>解决代码>或<代码> 代码拒绝回调被排在作业队列中。
最后,事件循环永久监听调用堆栈是否为空。如果调用堆栈为空,则事件循环查看作业队列或任务队列,并将准备执行的任何回调分派到调用堆栈中。
3。作业队列与任务队列
我们从事件循环的角度来看这个实验,我将对代码执行进行一步一步的分析。
)调用堆栈执行<代码> setTimeout (…,0)代码>并计划一个计时器,<代码>超时()代码>回调存储在Web API中:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img - slk0aua5 - 1611275604642) (/img/bVcMQdg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img - zr7usytk - 1611275604643) (/img/bVcMQc9)]
B)调用堆栈执行<代码> Promise.resolve(真)(解决)代码>并安排一个<代码> 代码>承诺解决方案。<代码>解决()代码>回调存储在Web API中:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img - jtwsnlys - 1611275604646) (/img/bVcMQdh)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img - k5crhqzn - 1611275604648) (/img/bVcMQdi)]
C)承诺立即被解析,同时计时器也立即执行。这样,定时器回调<代码>超时()代码>进入任务队列,<代码> 代码>承诺回调<代码>解决()代码>进入作业队列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img - imflb2yj - 1611275604649) (/img/bVcMQdS)]
D)现在是有趣的部分:作业队列(微任务)优先级高于任务队列(宏任务)。事件循环从作业队列中取出承诺回调<代码>解决()> 代码并将其放入调用堆栈中。然后,调用堆栈执行承诺回调