【问题标题】:setTimeout does not work设置超时不起作用
【发布时间】:2011-12-04 14:27:51
【问题描述】:

我想在执行其他(可视化)脚本之前加载一个 OWL 文件。为此,我尝试了

$(document).ready

function visualize (file) {
if (!file)
    {setTimeout(visualize(file), 2000)}
else
    {jQuery(function($){visFeaturePool.init(file)})}}

我认为 setTimeout 必须是可能的,但这不起作用。我抛出错误: Uncaught RangeError: Maximum call stack size exceeded,所以它不会等待,它只是调用可视化函数,直到堆栈已满。

有人知道我做错了什么吗? 谢谢!

【问题讨论】:

标签: javascript jquery owl


【解决方案1】:

代替

// #1
setTimeout(visualize(file), 2000);

你想要的

// #2
setTimeout(function() {
    visualize(file);
}, 2000);

或者在现代浏览器上,您可以提供参数以在延迟后传递给函数:

// #3
setTimeout(visualize, 2000, file);

这三个解释:

  1. (正如 SLaks 提到的)这会调用 visualize 立即,然后将其返回值传递给 setTimeout(并且由于 visualize 调用自身,它会不断递归调用自身,最终堆栈溢出错误)。
  2. 这会将函数引用传递给setTimeout,当调用该函数引用时,将调用visualize 并将file 参数传递给它(其值为然后)。我们传递给setTimeout 的函数将可以访问file 参数,即使您的代码已经运行并返回,因为该函数是创建它的上下文的闭包 ,其中包括file。更多:Closures are not complicated 请注意,file 变量的值是在计时器触发时读取的,而不是在您设置它时读取的。
  3. 这会将visualize 函数引用传递给setTimeout(注意我们后面没有()(file))并且还将file 传递给setTimeout,使用它的值设置通话。稍后,在现代环境中,setTimeout 将在稍后调用时将其传递给函数。

#2 和#3 之间有一个重要区别:对于#2,如果在调用setTimeout 和计时器到期之间更改filevisualize 将看到file 的新值。但是,对于#3,它不会。两者都有其用途。以下是这种差异的一个示例:

let file = 1;

// #2, using "file" when the timer fires, not when you set it up
setTimeout(function() { visualize(file); }, 2000); // Shows 2

// #3, using "file" right away when setting up the timer
setTimeout(visualize, 2000, file); // Shows 1

file = 2;

function visualize(value) {
    console.log(value);
}

如果您需要 #3 在不支持 setTimeout 的额外参数的环境中立即读取 file(而不是等到计时器触发)的行为,您可以这样做:

// #4 (for environments that don't support #3)
setTimeout(visualize.bind(null, file), 2000);

【讨论】:

  • 非常感谢您的帮助,出于某种原因,每个人都坚持使用 setTimeout(function(file), milliseconds);这根本不起作用,这节省了我的时间。
【解决方案2】:

setTimeout(visualize(file), 2000)立即调用visualize并将其结果传递给setTimeout,就像任何其他函数调用一样。

【讨论】:

    【解决方案3】:

    试试这个:

    function visualize (file) {
      if (!file)
        {setTimeout(function(){visualize(file);}, 2000)}
      else
        {jQuery(function($){visFeaturePool.init(file)})}}
    

    通过这种方式,您可以为 setTimeout 提供一个匿名函数,该函数将在计划时执行,并且您可以使用 file 之类的闭包传递参数以进行可视化。

    【讨论】:

      【解决方案4】:
      setTimeout(visualize, 2000, file);
      

      也可以。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 1970-01-01
        • 2019-07-22
        • 2019-04-08
        • 2016-06-22
        相关资源
        最近更新 更多