【问题标题】:Understanding Threading/Synchronicity Through JS's setTimeout通过 JS 的 setTimeout 了解线程/同步性
【发布时间】:2013-06-22 02:56:54
【问题描述】:

Javascript 的 setTimeout 函数让我重新评估我对 javascript 的了解。今天早些时候,我遇到了这样的 for 循环:

for (i = 0; i < length; i++) {
    setTimeout(executeOtherCode, 5000)
}

我希望这段代码执行的操作是执行 executeOtherCode 函数,“休眠”5 秒,然后继续下一次迭代。相反,我得到的是同时执行长度时间的 executeOtherCode。

所以据我了解,setTimeout 是一个异步函数调用。它是否正确?然而,如果我要执行一个常规函数,我们称之为 hugeFunction(),它需要 1 分钟才能执行,下一行代码在该函数返回之前不会执行,对吗?那么为什么两者不同呢?只是语言设计的选择?

我在 jQuery 中看到过以类似异步方式运行的其他函数,例如 getJSON。仅仅是知道哪些函数被定义为异步的问题,还是有某种模式可以识别它们?如果是这样,是什么?

【问题讨论】:

  • 通常异步函数是处理通过网络检索数据或某种 I/O 操作的函数(例如,HTML5 的新 IndexedDB 和 WebWorkers 特性中的一些方法)。除此之外,没有真正一致的方式来识别它们。您只需查看您正在使用的库的文档即可。
  • “我得到的是同时执行OtherCode” - 不,你没有。该代码排队 executeOtherCode() 以在 5000 毫秒后调用 length 次,同时当前块继续。每次超时都会尽可能晚地接近 5000 毫秒但不是在其他 JS 已经在执行时,所以每个超时都一个接一个地执行,而不是同时执行,而不是多线程。它只是似乎同时发生,因为两者之间没有明显的延迟。

标签: javascript jquery


【解决方案1】:

一般情况下,除特殊情况外 - JavaScript 会按顺序同步执行。

setTimeout(executeOtherCode, 5000)

正在告诉“在 5 秒内,运行函数 executeOtherCode”。它继续运行循环,它不会“阻止”执行。

在 5 秒内,事件循环将注意到设置了一个计时器(嗯,length 计时器)并将执行它们(一个接一个)。

如果你想让函数彼此延迟 5 秒执行,你需要告诉下一个函数在上一个函数完成后 5 秒执行,这种模式称为异步信号量。

一般的经验法则是如果它进行 I/O,它应该是异步的,这就是为什么 AJAX 是异步的(以及其他 HTTP 请求,如脚本标签注入)并且交互事件是异步的异步(例如,JavaScript 对点击做出反应,它不会等待它们)。计时器(setTimeout 和 setInterval 也是异步的)。

其他一切都是同步的。

现在,一些函数可能使用这些其他函数,但there is no silver bullet 可以找出哪个是哪个。只需清除文档即可。大多数异步函数都有一个回调参数(如executeOtherCode的第一个参数)但有些没有,有些函数接受回调但不是异步的。

【讨论】:

  • +1。并且大部分 JavaScript 以单线程方式执行(HTML5 WebWorkers 除外)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
相关资源
最近更新 更多