Javascript setTimeout 是不是停止其他脚本执行

Posted

技术标签:

【中文标题】Javascript setTimeout 是不是停止其他脚本执行【英文标题】: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 文件中,我不会干扰它,因为它使用了许多其他功能而且情况可能并不总是相同 【参考方案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中清楚的查看。您可以看到,给定随机时间数组waitTimesArray.map 函数将首先打印出所有time[index]=waitTimes[index] 值,然后当setTimeoutwaitTimes[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

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

【讨论】:

以上是关于Javascript setTimeout 是不是停止其他脚本执行的主要内容,如果未能解决你的问题,请参考以下文章

setTimeout()

在 setTimeout 中使用异步是不是有效?

JavaScript定时器 setTimeout与setInterval 浅析

setTimeout(call,0)作用

setTimeout那些事儿

javascript学习02