【问题标题】:Is calling setTimeout with a negative delay ok?以负延迟调用 setTimeout 可以吗?
【发布时间】:2012-01-15 21:18:54
【问题描述】:

以下 sn-p 设置了我希望至少持续一秒钟的超时:

var currentTimeMillis = new Date().getTime();
// do stuff...
var sleepTime = 1000 - (new Date().getTime() - currentTimeMillis);

鉴于sleepTime 可以是负数,这样调用setTimeout 是否安全,如下所示:

setTimeout(callback, sleepTime)

或者我需要在调用setTimeout之前检查负值吗?

【问题讨论】:

    标签: javascript settimeout


    【解决方案1】:

    根据MDN 参考,规范要求有一个最小超时时间。

    如果你提供的东西少于这个(HTML5 规范说 4 毫秒),那么浏览器将忽略你的延迟并使用最小值。

    所以负数应该没问题,因为它会小于最小值。


    显然,情况并非总是如此(Web 开发并非总是如此!)。根据(http://programming.aiham.net/tag/browser-compatibility/):

    为 setTimeout 提供一个负时间并不总是会导致 回调函数被调用。这适用于其他浏览器,但在 Internet Explorer (8 或更低) 你必须确保任何负面 时间变为零。

    我自己没有测试过这个,但就像 Thomasz 说的,安全一点可能更好。

    【讨论】:

    • 拧 IE8。你没有超时!
    • 在使用来自developer.microsoft.com/en-us/microsoft-edge/tools/vms 的VM 之一在IE 8 上进行测试后,我可以确认,如果您通过负超时,IE 8 的setTimeout 实现确实不会执行您的函数。至少 IE 8 已经足够古老,大多数我们可以放心地忽略它。
    【解决方案2】:

    安全总比后悔好:

    setTimeout(callback, Math.max(sleepTime, 0))
    

    【讨论】:

    • 啊酷,不知为何我觉得我必须做if (sleepTime > 0) setTimeout(...) else,那样会有点丑。
    • 如果性能有问题,总会有setTimeout(callback,sleepTime>0?sleepTime:0)
    【解决方案3】:

    您也可以使用条件语句,如下所示:

    if (sleepTime < 0) {
      sleepTime = 0;
    }
    setTimeout(callback, sleepTime);
    

    【讨论】:

    • 或者使用三元语句setTimeout(callback, sleepTime &gt; 0 ? sleepTime : 0)
    • 这正是上面这个答案。
    【解决方案4】:

    嗯……上面提到的解决方案解决了调用setTimeout的问题,所以每次调用都需要写。直接在setTimeout解决不是更好吗?

    // Run this once.
    (function(){
        var oldSetTimeout = setTimeout
        setTimeout = function(callback, delay){
            return oldSetTimeout(callback, Math.max(delay, 0))
        }
    })()
    
    // Call setTimeout safely with a negative delay.
    setTimeout(function(){ console.log("Hello World") }, -42)
    

    【讨论】:

      【解决方案5】:

      是的,可以像这样以毫秒为单位使用负超时。

              setTimeout(() => {
              btn.style.top = '16.2%';
              btn.style.left = '35.8%';
              btn.style.transition = 'all 1.2s ease';
              },-1.2*1000);
      

      此代码将在延迟 1.2*1000 秒、style topstyle left 后在 id btn 按钮上启动 transition

      【讨论】:

        猜你喜欢
        • 2020-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-23
        • 2012-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多