我知道setTimeout()内部的回调函数将等待,直到附加到它的计时器到期,并被推入回调队列。另一方面,一旦承诺被实现或被拒绝,它的回调就会被推送到具有更高优先级的微任务队列中。
我的问题是哪一次更快: promise中的setTimeout还是简单的setTimeout。如果前一个不再放在微任务队列中,为什么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
现在让我们假设我忘记了1秒的延迟,现在promise总是首先出现,因为在微任务队列中调度的回调具有更高的优先级
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');
});
发布于 2021-10-20 17:43:52
setTimeout的实现方式是在给定的最小延迟后执行,并在浏览器线程空闲时执行它。因此,举个例子,如果你指定延迟参数的值为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)
);
setTimeout将始终首先记录其结果,因为它将在下一个事件周期中可靠地执行。
另一方面,promise中的setTimeout将有两个事件周期,直到执行控制台日志(一个用于promise resolve,另一个用于setTimeout函数中的回调)。
请阅读延迟时间超过指定时间的原因- https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
有关JS事件循环的更多信息- https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
https://stackoverflow.com/questions/69650340
复制相似问题