【问题标题】:In javascript how do asynchronous callbacks work in a single thread?在javascript中,异步回调如何在单个线程中工作?
【发布时间】:2014-01-04 11:55:15
【问题描述】:

对于下面计划调用这 2 个图像的“onload”的 onload 2 个函数,如何保证一个会在另一个开始之前完全完成?在这个单线程环境中需要触发的回调幕后是否有队列?

如果 entryFunction 永远不会停止循环,它是否会暂停其线程并让步给 doWorks() 之一?

我听说 javascript 不是多线程的,那么 entryFunction() 是否对这些异步函数调用产生/暂停?

function entryFunction() {
  var obj = new Image();
  var obj2 = new Image();
  // ...
  obj.onload = function() { dowork(); }
  obj2.onload = function() { dowork(); }

  while (1) {
    console.log("Actual work is being done");
  }
}

function dowork() {
  doThis();
  doThat();
}

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您的代码永远不会离开while 循环。因为 JavaScript 只有一个线程,所以您必须在每个函数中 return 才能将控制权返回给环境。

    在您的示例中,您的示例将导致您的浏览器在单独的线程中设置和下载图像(因为浏览器是多线程的)。下载图像后,环境将对onload() 的调用进行排队。这些将在您的 JavaScript 程序下一次将控制权返回给环境时运行。

    但由于您在 while 循环中无限期地持有控制权,因此控制权永远不会返回到环境中,排队的事件也永远不会运行。

    【讨论】:

      【解决方案2】:

      没有任何保证。

      您只能保证它们不会同时运行。

      while循环会阻止其他js运行。

      浏览器本身并不局限于单线程实现。 Javascript 本身在单个运行循环中运行,但这并不能保证浏览器中的其余部分会执行(而且它们不会执行)。

      【讨论】:

        【解决方案3】:

        我上面的两个正确答案(原始 JS 是单线程的,并且会在此期间阻塞)。也就是说,有一个名为 Web Workers 的新 HTML5 API 可以让您在 JS 中实现并发。

        http://www.html5rocks.com/en/tutorials/workers/basics/

        它们是“真正的”(就开发人员而言)并发。有些浏览器确实将它们实现为真正的并发,有些浏览器在幕后使用协程和调度程序来伪造它。

        【讨论】:

          【解决方案4】:

          Javascript 不是多线程的,但它是事件驱动的。

          dowork() 将被调用,除非 onload() 被某些东西调用。

          除此之外,while(1) 不会导致代码继续前进。 而不是while(1) 使用setInterval 或setTimeout。这样函数就不会阻塞其余的代码。

          如果new Image() 导致onload() 被调用,因为在new Image() 之后设置了onload,则可能出现竞争条件

          【讨论】:

            猜你喜欢
            • 2012-02-17
            • 1970-01-01
            • 1970-01-01
            • 2019-06-08
            • 2018-12-03
            • 1970-01-01
            • 2011-01-11
            • 1970-01-01
            相关资源
            最近更新 更多