1

我正在构建一个 JavaScript 库。我一直在研究一个像这样工作的延迟函数:

function delay(ms) {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > ms){
            break;
        }
    }
}

我的想法是我可以做这样的事情:

window.onload = function() {
  delay(5000);  //this function will act 5 seconds after the page loads
  document.getElementById('Header').innerHTML = 'Welcome';
};

延迟工作正常,但它会停止页面上的所有 javascript,而不仅仅是延迟window.onload函数。

有谁知道我能做什么?

4

3 回答 3

6

使用 setTimeout 而不是您的延迟方法。它不会阻塞用户界面并且更干净。

setTimeout(function() {
   document.getElementById('Header').innerHTML = 'Welcome';
}, 5000);
于 2013-06-14T15:36:11.517 回答
4

我认为您的问题(以及对Patrick D 的回答)是基于误解。

没有办法实现你想要的代码。

JavaScript 环境是单线程的。(让我们暂时忽略网络工作者。)这意味着每一行都在它之前的那一行之后执行。

如果您有一个函数占用这个(一个也是唯一的)线程 5 秒,那么在这 5 秒内不会运行其他任何东西。就这么简单。

我们在 JavaScript 世界中解决这个问题的方法是利用异步编程,它利用回调。该setTimeout函数是解决此问题的正确方法。

现在,你可以做到这一点。假设您想要一个函数,给定一些函数fn,返回一个新函数,该函数fn在设定的延迟后执行。你可以实现这个:

Function.prototype.delay = function(ms) {
    var fn = this;
    return function() {
        setTimeout(fn, ms);
    };
};

然后,您可以假设编写如下代码:

function foo() {
  // something or other
}

var fooDelayed = foo.delay(5000);

// Now this line will execute foo after 5 seconds.
fooDelayed();

如果你真的想要这样的东西,这是可能的。但它本质上仍然是一个包装器setTimeout:这是无法避免的。

看到这个 jsFiddle展示了这个想法。

于 2013-06-14T15:52:22.003 回答
2

如果你真的想围绕 构建一个函数setTimeout(),你可以这样做:

function delay(ms, callback) {
  setTimeout(callback, ms);
}

如果没有阻塞机制,绝对没有其他方法可以延迟代码块的动作或执行。

而且由于setTimeout()异步执行,您始终必须提供回调函数!

于 2013-06-14T15:44:07.137 回答