promise和settimeout执行先后的区别 promise.then和settimeout
1.实验
【promise和settimeout执行先后的区别 promise.then和settimeout】我们来做个实验 。哪个执行得更快:立即解决的 Promise 还是立即setTimeout
(也就是0毫秒的setTimeout)?
Promise.resolve(1).then(function resolve() {
console.log('Resolved!');
});
setTimeout(function timeout() {
console.log('Timed out!');
}, 0);
// 'Resolved!'
// 'Timed out!'
promise.resolve(1)
是一个静态函数,它返回一个立即解析的promise
。setTimeout(callback, 0)
以0毫秒
的延迟执行回调函数 。
我们可以看到先打印,再打印Timeout completed!
,立即解决的 promise 比立即更快 。
是因为Promise.resolve(true).then(...)
在setTimeout(..., 0)
之前被调用了,所以 Promise 过程会更快吗? 公平的问题 。
所以,我们稍微更改一下实验条件,然后先调用:
setTimeout(function timeout() {
console.log();
}, 0);
Promise.resolve(1).then(function resolve() {
console.log();
});
在之前被调用 。但,还是先打印Resolved!
在打印 。
这是为啥呢?
2.事件循环
与异步 JS 相关的问题可以通过研究事件循环来回答 。我们回顾一下异步 JS 工作方式的主要组成部分 。
文章插图
调用堆栈是一个LIFO(后进先出)结构,它存储在代码执行期间创建的执行上下文 。简单地说,调用堆栈执行这些函数 。
Web api是异步操作(fetch 请求、promise、计时器)及其回调等待完成的地方 。
task queue (任务队列)是一个FIFO(先进先出)结构,它保存准备执行的异步操作的回调 。例如,超时的
setTimeout()
的回调函数或准备执行的单击按钮事件处理程序都在任务队列中排队 。job queue (作业队列)是一个FIFO(先入先出)结构,它保存准备执行的 的回调 。例如,已完成的承诺的
resolve
或reject
回调被排在作业队列中 。最后,事件循环永久监听调用堆栈是否为空 。如果调用堆栈为空,则事件循环作业队列或任务队列,并将准备执行的任何回调分派到调用堆栈中 。
3.作业队列与任务队列
我们从事件循环的角度来看这个实验,我将对代码执行进行一步一步的分析 。
A)调用堆栈执行并计划一个计时器,
timeout()
回调存储在Web API中:文章插图
推荐阅读
- 唐朝品级最高的官?唐朝的官职名称和品级
- 手机系统天玑和骁龙哪个好 手机处理器天玑和骁龙哪个好-
- 船员|职场是一个复杂的地方,领导会有很多的个性和要求
- 山楂和菊花能一起泡水喝吗 山楂和菊花一起泡水喝可以减肥吗
- 小孩总是不听话和大人顶嘴怎么办
- 吊牌怎么区分材质,吊牌怎么区分材质和木质
- 花红片和千金片哪个好
- 不伤身体的壮阳药
- 宫炎平和千金片哪个好
- 千金片和三金片的区别