简体   繁体   English

Promise 中的 setTimeout 与 setTimeout

[英]setTimeout inside Promise vs setTimeout

I know that a callback function inside setTimeout() will wait until the timer attached to it expires and the gets pushed into a callback queue.我知道setTimeout()中的回调函数将等到附加到它的计时器到期并将其推送到回调队列中。 On the other hand, a promise, once fulfilled or rejected gets its callback pushed into a microtask queue, which has higher priority.另一方面,一个承诺,一旦完成或被拒绝,就会将其回调推送到具有更高优先级的微任务队列中。

My question is which once is faster: a setTimeout inside a promise or a simple setTimeout .我的问题是哪个更快:promise 中的setTimeout或简单的setTimeout If the former one is not placed onto the microtask queue anymore, why is the setTimeout alone running first instead of the other way around?如果前一个不再被放入微任务队列,为什么setTimeout单独首先运行而不是相反?

 setTimeout(() => { console.log('timeout'); }, 1000); let promise = new Promise(function(resolve, reject) { // This is run automatically, let's run resolve after 1 second setTimeout(() => resolve('promise!'), 1000); }); promise.then( (result) => console.log(result), (err) => console.log(error) ); // output: timeout -> promise || and not || promise -> timeout

Now let's suppose I forget the 1 second delay, now the promise will always appear first since the callback scheduled inside the microtask queue has higher priority现在让我们假设我忘记了 1 秒延迟,现在承诺将始终首先出现,因为微任务队列中调度的回调具有更高的优先级

 setTimeout(() => { console.log('timeout'); }, 0); let promise = new Promise(function(resolve, reject) { // This is run automatically, let's run resolve after 1 second // setTimeout(() => resolve('promise!'), 1000); resolve(''); }); promise.then(() => { console.log('promise'); });

setTimeout is implemented in a way it's meant to execute after a minimum given delay, and once the browser's thread is free to execute it. setTimeout的实现方式是在给定的最小延迟后执行,并且一旦浏览器的线程可以自由执行它。 so, for an example, if you specify a value of 0 for the delay parameter and you think it will execute "immediately", it won't.因此,例如,如果您为延迟参数指定值 0 并且您认为它会“立即”执行,则不会。 it will, more accurately, run in the next event cycle (which is part of the event loop - concurrency model which is responsible for executing the code).更准确地说,它将在下一个事件循环中运行(这是事件循环的一部分 - 负责执行代码的并发模型)。

Let's take the example for a delay value of 0.我们以延迟值为 0 为例。

 setTimeout(() => { console.log('timeout'); }, 0); let promise = new Promise(function(resolve, reject) { setTimeout(() => resolve('promise!'), 0); }); promise.then( (result) => console.log(result), (err) => console.log(error) );

The setTimeout will always log it's result first because it will execute surely in the next event cycle. setTimeout将始终首先记录它的结果,因为它肯定会在下一个事件周期中执行。

The setTimeout in the promise on the other hand, will have 2 event cycles until the console log will execute (one for the promise resolve and the other one for the callback in the setTimeout function).另一方面,promise 中的setTimeout将有 2 个事件周期,直到控制台日志执行(一个用于 promise 解析,另一个用于 setTimeout 函数中的回调)。

Please read reason for delays longer then specified - https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified请阅读延迟时间超过指定的原因 - https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified

More about the JS event loop - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop更多关于 JS 事件循环 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM