【问题标题】:Does Javascript setTimeout stop other script executionJavascript setTimeout 是否停止其他脚本执行
【发布时间】:2012-04-21 10:10:18
【问题描述】:

我指的是this。一切都还不清楚。

  • 我有一个更新树的 JS 函数 fillTree(),它有复选框。
  • 我还有另一个函数 checkSelectedBoxes(),它在 window.onload 上执行,它检查选定的复选框。
  • 现在还连接了许多其他功能。

我的问题:

  • 如果我使用setTimeout(),其他脚本函数是否也会停止并等待我的函数完成加载?

这可能是什么情况:

function fillTree(){...}
function checkSelectedBoxes(){...}

fillTree(); // This take time to get data. onLoad() doesnt work.
setTimeout(function(){ checkSelectedBoxes()  },5000);

即使增加了时间间隔,这也会返回空值。 fillTree() 是否暂停执行?

【问题讨论】:

  • 不,setTimeout 不会暂停其他代码的执行。如果您尝试在完成fillTree() 时调用checkSelectedBoxes(),为什么不将其作为回调参数传递,或者只是在fillTree() 的末尾传递?
  • @RoryMcCrossan 谢谢,您的回答似乎是最好的解决方案,但它是我正在使用的 CMS,并且树设置在其他一些 js 文件中,我不会干扰它,因为它使用了许多其他功能而且情况可能并不总是相同

标签: javascript


【解决方案1】:

不,setTimeout 不等你(因此,JS 没有暂停功能)。 setTimeout 所做的是稍后将该任务搁置一旁,并允许执行下一行。当达到超时时,它会将该任务插入到执行行中。当没有其他代码在运行时,它会执行指定的函数。

你想要做的是给你的fillTree()一个回调并在它完成时执行。

function fillTree(callback){

    //do something very long

    callback(); //execute passed function when it's done
}

fillTree(function(){
    checkSelectedBoxes(); //executes only when fillTree finishes
})

【讨论】:

  • 谢谢。这清除了一切。我会在 8 分钟内接受:P。问题也没有说明,但你能告诉我这样的案例应该是我的方法吗?
  • fillTree 到底是做什么的?是 Ajax 调用吗? DOM 行走?什么需要这么长时间?
  • “它将该任务插入执行行”并不完全准确。它不会中断用户代码,也不会同时运行它;它只会在没有运行 JS 用户代码并且已达到超时时间时运行。
  • 好点。但简单来说,就是这样。我会更新的。
  • 这是一个非常重要的方面,因为这允许程序员对重入做出假设(例如它不会重入)。
【解决方案2】:

它是我正在使用的 CMS,并且树设置在其他一些 js 文件中,我不会干涉,因为它使用了许多其他功能,并且情况可能并不总是相同

如果无法修改fillTree() 函数,您可以将其包装在您自己的函数中并对其应用回调函数。试试这个:

function doStuff(callback) {
    fillTree();

    // Call the callback parameter (checkSelectedBoxes() in this case)
    // when fillTree() has completed
    callback();
}

doStuff(checkSelectedBoxes);

【讨论】:

  • 您的回答对我的功能有所帮助,但我的问题的答案是由@joseph 给出的。谢谢!
【解决方案3】:

setTimeout函数不等待执行,可以在下面的sn-p中清楚的查看。您可以看到,给定随机时间数组waitTimes,Array.map 函数将首先打印出所有time[index]=waitTimes[index] 值,然后当setTimeout 在waitTimes[index] 毫秒后被触发时wait[index]=waitTimes[index]。

var console = {
  log: function(s) {
    document.getElementById("console").innerHTML += s + "<br/>"
  }
}
var roundDecimals = function(num, pos) {
  pos = pos || 4;
  return (Math.round(num * Math.pow(10, pos)) / Math.pow(10, pos));
}
var arrayRangeMap = function(a, block) {
  c = [];
  while (a--) c[a] = block();
  return c
};
var getRandomArbitrary = function(min, max) {
    return (Math.random() * (max - min) + min);
  }
  // random 10 wait times, 3 decimal positions
var waitTimes = arrayRangeMap(10, function() {
  return roundDecimals(getRandomArbitrary(0.250, 0.5, 3) * 1000, 2);
});

waitTimes.map(function(item, index) {
  setTimeout(function() {
    console.log("wait[" + index + "]=" + item);
  }, item);
  console.log("time[" + index + "]=" + item);
});
&lt;div id="console" /&gt;

【讨论】:

    【解决方案4】:

    我刚刚做了一个可能感兴趣的测试:

    <!DOCTYPE html>
    <html>
      <head>
        <script>
    
    /* test: if returns in around 1000ms, must interrupt, otherwise it is indeed
       not going to let timeout work until work is done. */    
    window.onload = function() {
        var before = performance.now();
        setTimeout(function() {
            alert('completed in ~' + (performance.now() - before) + ' nanoseconds.');
        }, 1000);
    
        /* count to 2^31 - 1... takes 8 seconds on my computer */
        for (var i = 0; i < 0xffffffff; ++i) {
            /* me busy, leave me alone */ 
        }
    };      
        </script>
      </head>
      <body>
      </body>
    </html>
    

    我现在真的很好奇 JavaScript 是如何知道特定时间已过的。它会产生一个休眠一段时间的线程吗?如果是这样,有多少线程睡眠有限制,或者睡眠线程是否“存储”直到需要它们?很混乱。

    我认为这与它有关

    “如果不需要正好是 1s,那么就睡一秒钟。 usleep 和 sleep 使当前线程进入高效的等待状态 这至少是您请求的时间量(然后它变成 有资格再次安排)。

    如果您不想接近准确时间,则无需检查 时钟()。”

    --pthread sleep function, cpu consumption

    所以我猜操作系统为你做了调度,此时它会中断引擎,引擎停止世界并将超时函数放在队列顶部以尽快执行?

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多