首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在函数开头放置具有零延迟的setTimeout时,代码执行速度更快:为什么会发生这种情况?

在函数开头放置具有零延迟的setTimeout时,代码执行速度更快:为什么会发生这种情况?
EN

Stack Overflow用户
提问于 2021-11-13 04:17:21
回答 1查看 153关注 0票数 1

在下面的文章use-case 1中,它们更改了setTimeout调用在count函数中的位置:

https://javascript.info/event-loop#use-case-1-splitting-cpu-hungry-tasks

在第二种情况下,速度要快得多,他们用以下一句加以解释:

如果您运行它,很容易注意到它花费的时间要少得多。 为什么? 这很简单:正如您所记住的,对于许多嵌套的setTimeout调用,浏览器内的最小延迟为4ms。即使我们设置为0,它也是4ms (或更多)。所以我们安排的时间越早,它的运行就越快。

对我来说,这是一个非常不清楚的解释,我完全不明白它们的意思。有谁能更清楚和详细地解释为什么这两种情况需要不同的时间?

EN

回答 1

Stack Overflow用户

发布于 2021-11-13 11:43:19

setTimeout(fn, t)将同步调度 fnnow + t开火。

然后,引用中的解释是:如果在锁定计算机一段时间之前就安排了任务,那么它将在启动之前启动,而不是在计划完成之后。

代码语言:javascript
复制
// now = wall clock 0;
setTimeout(fn, 1000); // schedules `fn` to fire at wall clock 0 + 1000 = 1000
lockCPUFor(5000); 
// now = wall clock 5000;
setTimeout(fn, 1000); // schedules `fn` to fire at wall clock 5000 + 1000 = 6000;

在任务结束时,我们现在是= 5000 +几毫秒。第一个超时由4s传递,因此我们将立即执行它。然而,第二次超时计划在大约一秒钟内启动,所以我们将等待大约一秒钟。

代码语言:javascript
复制
const origin = performance.now();
function fn(name) {
  console.log(name, performance.now() - origin);
}
fn("begin"); // ~0.05
setTimeout(() => fn("setTimeout before"), 1000); // ~ 5010
lockCPUFor(5000);
setTimeout(() => fn("setTimeout after"), 1000);  // ~6000

function lockCPUFor(t) {
  const now = performance.now();
  while (performance.now() - now < t) {}
}

但是在我们的例子中,延迟是0而不是1000,所以这不重要。

正如你引用的那样,传递0并不意味着你真的会有一个零超时。有些环境(例如和node.js)总是有1ms的最小超时(尽管Chrome正在积极尝试会删除最小超时),火狐也会添加一些最小超时,“在页面加载时”(实际上,页面加载超时的他们有一个特殊的任务队列。比任何其他任务队列的优先级都要低)。

跟随HTML规范的每个UA在嵌套的第5层将有一个4ms的超时:

代码语言:javascript
复制
let startTime;
let i = 0;
const fn = () => {
  console.log("iteration #%s took %sms", i + 1, performance.now() - startTime);
  if (++i < 6) {
    startTime = performance.now();
    setTimeout(fn, 0);
  }
}
const startTest = () => {
  startTime = performance.now();
  setTimeout(fn, 0)
}
// avoid Firefox's weird at-load task queue
onload = startTest;

因此,即使您通过0,这几个由UA自动添加的ms也会影响回调何时被调度,而在长任务之前的调度将确实允许避免大多数这些限制(如果长任务持续时间更长)。

但是请注意,如果您需要比setTimeout更快地连接到事件循环,那么有办法

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69951422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档