使用setTimeout()的JavaScript执行顺序

12

假设我有以下代码:

function testA {
   setTimeout('testB()', 1000);
   doLong();
}

function testB {
   doSomething();
}

function doLong() {
   //takes a few seconds to do something
}

我执行testA()。我已经了解到JavaScript是单线程的。在1000毫秒后,当testB()的超时时间到达时会发生什么?

我能想到一些可能性:

  • testB()排队等待在doLong()和其他调用完成后执行。
  • doLong()立即终止,然后开始执行testB()
  • doLong()被给予更长的时间来执行,然后在自动或提示用户后停止,并开始执行testB()
  • doLong()被暂停,testB()开始执行。在testB()完成后,doLong()恢复执行。

正确答案是什么?这是实现相关的还是标准的一部分?*

这个问题与本题类似,但据我所知并不完全相同。

如果您能推荐任何链接以更好地理解JavaScript执行,将不胜感激。

谢谢!

* 是的,我知道不是所有浏览器都遵循标准 :(

1个回答

11
你的第一个猜测是正确的: testB()被排队等待执行,直到doLong()和它所调用的其他函数完成为止。 如果testA需要超过一秒钟才能完成,testB将不得不等待。
此外,你应该写setTimeout(testB, 1000)而不是setTimeout('testB()', 1000)。向setTimeout发送字符串,就像使用eval一样,通常被认为是有害的,会让你招惹敌人 ;)

我开始相信 setTimeout(function() { testB(); }, 1000); 是最好的方法,但是我被误导了吗? - Shadow The Spring Wizard
2
@Shadow Wizard:是的,基本上是误导了。据我所知,你的方法和我的方法没有区别(当然,我的方法更短 :D)。为了说明这一点,想象一下,如果我们将你的表达式提取到一个变量中:var f = function() { testB(); }; setTimeout(f, 1000);。仍然具有相同的含义,但现在你可以看到冗余性。 - Jakob
1
谢谢你们的回答和建议,关于将函数传递给setTimeout而不是字符串。看起来我一直在阅读的教程有点可疑 ;) - Brian Beckett
与最新的Chrome(版本62)不同,这种情况不会发生。testB()将首先执行,然后执行doLong()。 - coderz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接