setTimeout(fn, 0) 和 setTimeout(fn, 1) 有什么区别?

IT技术 javascript jquery
2021-03-08 14:27:42

所述的jQuery源设有的用途setTimeout与两个01作为第二个参数。我的印象是它们都意味着“尽快执行该功能”。

这个对吗?两者有区别吗?

6个回答

setTimeout最小超时时间为 4 毫秒。所以两者实际上没有区别。

如果当前运行的任务是 setTimeout() 方法创建的任务,并且 timeout 小于 4,则将 timeout 增加到 4。

规格

编辑:正如艾哈迈德在评论中指出的那样,规范现在已经改变,所以目前的答案是,“这取决于。”

MDN 还在setTimeout()他们的文章并发模型和事件循环中解释了零延迟的使用
2021-04-16 14:27:42
实际上 - 据我记得 - 您定义的超时意味着是最早的时刻。如果您的 cpu 被大量使用,您的功能可能会晚得多。
2021-04-21 14:27:42
所有浏览器都遵循规范到 ms 的那一天对我们 Web 开发人员来说将是美好的一天 :D
2021-04-22 14:27:42
实际上您的假设是错误的,并且在规范中他们提到如果嵌套级别大于 5,并且超时小于 4,则将超时增加到 4。因此这仅在嵌套级别大于 5 时有效。
2021-05-07 14:27:42
@Ahmad 是的,您说得对,现已更新。在此回答时,将近 2 年前,规范中引用了我的回答中的话。
2021-05-09 14:27:42

我认为现在的答案是“视情况而定”。

我们可以在不同的平台和浏览器中运行代码:

function setTimeouts() {
  setTimeout(function() { console.log(2); }, 2);
  setTimeout(function() { console.log(1); }, 1);
  setTimeout(function() { console.log(0); }, 0);
}

for (var i = 0; i < 10; i++) {
  setTimeouts();
}

  1. 对于 Node.js,0转换为1,因此它们完全相同:https://github.com/nodejs/node/blob/master/lib/timers.js#L319,结果可能是:

     1
     0
     1
     0
     1
     0
     1
     0
     1
     0
     1
     0
     1
     0
     1
     0
     1
     0
     1
     0
     2
     2
     2
     2
     2
     2
     2
     2
     2
     2
    
  2. 对于 Chrome,结果与 Node.js 非常相似

  3. 对于 Firefox,大部分0将在之前打印1

     0
     0
     0
     0
     0
     0
     0
     0
     0
     0
     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
     2
     2
     2
     2
     2
     2
     2
     2
     2
     2
    

我不确定给出的答案是否正确。在 Chrome 中运行以下代码,0显然可以更快地调用绑定函数(只需在0之间切换计时器值1):

console.log("A");
console.log("B");
var start = new Date().getTime();
setTimeout(function() {
    console.log(new Date().getTime() - start);
}, 0);
console.log("C");
console.log("D");

0似乎在做类似 Node.js 的事情setImmediate,将指令推送到当前调用堆栈的末尾,同时1调用任何实现视为最小值的内容。

小更正:您在 Node 中所指的函数称为 process.nextTick,而 setImmediate 是 IE10 中的一个新介绍,它执行相同的操作。
2021-04-30 14:27:42
我发现在上述测试中使用0vs没有一致的优势1有时输出更大,有时输出0更大1
2021-05-02 14:27:42

在编程和计算上是有区别的,但你在执行它时不会看到区别,因为它只有 1 毫秒。

我想如果超时设置为 1 毫秒,它会暂停该脚本并允许其他脚本同时运行。您可能知道,JavaScript 是单线程的,所以这可能就是您的原因。


感谢molf 纠正了我的想法似乎设置为 ms 只是让它在事件循环的下一个滴答声中运行的一个技巧。

将其设置0为在事件循环的下一个滴答中运行代码的常见技巧,它根本不应该立即运行。
2021-04-20 14:27:42
为什么不会发生这种情况0ms呢?你有消息来源吗?
2021-04-23 14:27:42
如果设置为 0ms,它会立即运行,这才有意义。我没有消息来源,所以我写了“我会想象”
2021-05-04 14:27:42
@JanDragsbaek setTimeout 是异步的。此外,它的最短超时时间为 4、10 或 13 毫秒,具体取决于您的浏览器。
2021-05-14 14:27:42

出于为什么setTimeout(fn, 0)setTimeout(fn, 1)需要的原因,请查看为什么 setTimeout(fn, 0) 有时有用?.

从本质上讲,这意味着与其他浏览器任务(如页面渲染)相比,该方法执行起来不是很紧迫。此外,JavaScript 代码将在等待任务结束后运行。

实际操作中,使用 0 或 1 没有区别。这只是程序员的选择。理想情况下,编码员选择的数字低于 4,这可能是由于 Amaan 指出的原因。

顺便说一句,有关 JavaScript 计时器的基本信息,请参阅http://ejohn.org/blog/how-javascript-timers-work/