关于javascript:面试官为什么-Promise-比setTimeout-快

35次阅读

共计 2056 个字符,预计需要花费 6 分钟才能阅读完成。

作者:Milos Protic
译者:前端小智
起源:devinduct

有幻想,有干货,微信搜寻【大迁世界】关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

1. 试验

咱们来做个试验。哪个执行得更快: 立刻解决的 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)是一个动态函数,它返回一个立刻解析的 promisesetTimeout(callback, 0) 0 毫秒 的提早执行回调函数。

咱们能够看到先打印 'Resolved!',再打印Timeout completed!,立刻解决的 promise 比立刻setTimeout 更快。

是因为 Promise.resolve(true).then(...)setTimeout(..., 0)之前被调用了,所以 Promise 过程会更快吗?偏心的问题。

所以,咱们略微更改一下试验条件,而后先调用setTimeout(..., 0)

setTimeout(function timeout() {console.log('Timed out!');
}, 0);

Promise.resolve(1).then(function resolve() {console.log('Resolved!');
});

// 'Resolved!'
// 'Timed out!'

setTimeout(..., 0)Promise.resolve(true).then(...) 之前被调用。但,还是先打印 Resolved! 在打印'Timed out!'

这是为啥呢?

2. 事件循环

与异步 JS 相干的问题能够通过钻研事件循环来答复。咱们回顾一下异步 JS 工作形式的次要组成部分。

调用堆栈 是一个 LIFO(后进先出)构造,它存储在代码执行期间创立的执行上下文。简略地说,调用堆栈执行这些函数。

Web api 是异步操作 (fetch 申请、promise、计时器) 及其回调期待实现的中央。

task queue(工作队列)是一个 FIFO(先进先出) 构造,它保留筹备执行的异步操作的回调。例如,超时的 setTimeout() 的回调函数或筹备执行的单击按钮事件处理程序都在工作队列中排队。

job queue(作业队列)是一个 FIFO(先入先出)构造,它保留筹备执行的 promise 的回调。例如,已实现的承诺的resolvereject回调被排在作业队列中。

最初,事件循环永恒监听调用堆栈是否为空。如果调用堆栈为空,则事件循环查看作业队列或工作队列,并将筹备执行的任何回调分派到调用堆栈中。

3. 作业队列与工作队列

咱们从事件循环的角度来看这个试验,我将对代码执行进行一步一步的剖析。

A)调用堆栈执行 setTimeout(..., 0) 并打算一个计时器,timeout()回调存储在 Web API 中:

B)调用堆栈执行 Promise.resolve(true).then(resolve)并安顿一个 promise 解决方案。resolved()回调存储在 Web API 中:

C)promise 立刻被解析,同时计时器也立刻执行。这样,定时器回调 timeout() 进入工作队列,promise回调 resolve() 进入作业队列

D)当初是乏味的局部:作业队列 (微工作) 优先级高于工作队列 (宏工作)。事件循环从作业队列中取出 promise 回调resolve() 并将其放入调用堆栈中。而后,调用堆栈执行 promise 回调resolve()

E)最初,事件循环将计时器回调 timeout() 从工作队列中出队到调用堆栈中。而后,调用堆栈执行计时器回调timeout()

调用堆栈为空,已实现脚本的执行。

总结

为什么立刻解决的 promise 比立刻执行定时器解决得更快?

因为事件循环优先级的存在,因而与工作队列(存储超时的 setTimeout() 回调)相比,作业队列(用于存储已实现的 Promise 回调)的优先级更高。

完~ 我是小智,我要去刷碗了,咱们下期见!


代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

原文:https://dmitripavlutin.com/ja…

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq44924588… 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

正文完
 0