当 JavaScript 是单线程语言时,如何在 JavaScript 中使用异步 none 阻塞代码?

How is it possible to have asynchronous none blocking code in JavaScript when JavaScript is a single threaded language?

我是 JavaScript 的新手,我习惯于通过创建工作线程在 Java 中创建异步 none 阻塞代码。

鉴于Java脚本是单线程语言,我不明白异步 none 阻塞代码在 Java 脚本中是如何工作的.

例如,PromisesCallbacks in JavaScript.

两者都是 none 阻塞,并允许主线程逐行继续执行程序的其余部分,并且只有在以后实现承诺时(例如:数据准备就绪)然后promise.resolve() 或执行回调。

现在,我很难理解哪个线程在准确跟踪 promise 何时 fulfilled/ready 或者如果主线程已经移动并忙于做不同的事情,回调准备好执行?

我的逻辑告诉我作为一个Java程序员,必须有一个后台工作线程负责在callback/promise准备好执行时通知主线程,这与Java脚本是单线程的,所以我一定是错的。

我希望对这个概念有一个很好的解释。 提前致谢!

有两种方法可以使用计算机实现并发行为:

  1. 您同时 运行 两台计算机(或处理器)(多线程)。

  2. 你在不同的任务之间切换得非常快,所以看起来他们会同时运行(多任务处理)。

现在 Java 经常在这些任务之间切换,而 JavaScript 只会在当前任务完成时切换任务;因此,代码不会 运行 并发地表现 "single-threaded".

Java脚本在 "single-threaded way" 中执行并不意味着底层引擎是单线程的。它不是,它使用一些线程来管理 I/O。每当您启动一个异步操作时,引擎都会将其委托给一个后台线程;然后,当任务完成时,另一个线程 returns 将结果返回到主线程,然后主线程将回调到 Java 脚本代码中。

您可以将 Java 脚本引擎视为在 ThreadPool 中启动线程的 TaskExecutor。但是,您只能控制 TaskExecutor.

承诺/回调阻塞。您可以 运行 这个例子:

function func1() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('func1');
      while (true) {}
      resolve();
    }, 0);
  });
}

function func2() {
  func1();
  func1();
  console.log('func2');
}

func2();

你会看到 func1 只打印一次,因为第一个执行 func1() 的 Promise 阻止了第二个被调用。

您可能认为每个代码块都放在(事件循环的)队列中。

对于异步调用,代码的异步部分是排队,等待事件循环到运行它。当然,事件循环本身是 JavaScript 应用程序中的单线程。

例如,如果将 while 循环移动到 func2() 的末尾,您将永远看不到 func1 被打印出来,因为函数 func2() 阻塞了队列,因此承诺永远不会解决。

作为调度程序工作的 "thread" 应该是应用程序之外的另一个线程,但由于它不是应用程序的一部分(由 JavaScript 开发人员/用户编写),我不认为JavaScript 不是 "single threaded language".