【问题标题】:Does wrapping a function in a promise cause the function's code to be executed in parallel by another thread?将函数包装在 Promise 中会导致函数的代码被另一个线程并行执行吗?
【发布时间】:2018-05-11 01:42:20
【问题描述】:

我已经阅读了很多关于 Promise 和 async/await 的文章。他们似乎都在处理返回承诺的 API 以及如何使用这些承诺。我还是有点迷茫。

假设我有一个包含三 (3) 个循环的函数。假设,每个循环执行一些需要五 (5) 秒才能完成的工作,将每次迭代的结果推送到该循环的数组中。这项工作是同步进行的(循环 1 运行,然后是循环 2,然后是循环 3)。

然后,该函数在返回之前对所有三个循环的结果执行一些操作。假设的总执行时间约为十六 (16) 秒。

如果将循环放入它们自己的函数中,包装在一个 promise 中,然后使用 await Promise.allasync function 中等待(在对结果进行处理之前),它们是否会并行执行(因为它们在事件循环,而不是调用堆栈),一旦所有三 (3) 个承诺都解决了,函数会继续吗?这比整个过程同步更快吗?

我想我对您何时/为什么要从同步 JS 创建自己的 Promise 感到困惑?

function loop1() {
  return new Promise((resolve, reject) => {
    let loop1Counter = 0
    const loop1Array = []
    while (loop1Counter < 10 **8) {
      // Do some work
      loop1Array.push(resultOfWork)
    }
    loop1Counter += 1
    resolve(loop1Array)
  }
}

async function test() {
  const promisesToAwait = [loop1(), loop2(), loop3()]
  const results = await Promise.all(promisesToAwait)
  // Do some work with results
  return something
}

【问题讨论】:

  • afaik 答案是“不”。
  • 我曾经问过一个类似的question。技术上可能会有所不同,但answer 适合他们。
  • 感谢您的链接。我发现它很有帮助。

标签: javascript


【解决方案1】:

JavaScript 执行是单线程的。这意味着如果不使用 WebWorker 之类的机制,任何 javascript 代码都不会并行执行。话虽如此,使用诸如承诺之类的异步代码执行同步 javascript 有几个原因。

  1. 您的代码需要一段时间才能执行。

Javascript 执行与浏览器中的 UI 共享相同的线程。这意味着如果您的代码需要 5 秒来执行,则用户浏览器将在此期间被阻止。您可以改为将执行分解为多个异步执行的块,这将允许 UI 保持响应。

  1. 您正在从现有异步函数参与承诺链。

有时需要混合异步和同步代码。 Promise 允许您将异步和同步代码组合到执行链中,而无需硬编码依赖项。

  1. 您遇到了堆栈大小限制。

根据您的代码和库的编写方式,有时您可能会出现堆栈失控,这可能导致堆栈大小异常或内存使用过多。通过异步执行一段代码,它获得了自己的新堆栈。

  1. 您正在执行库/框架中的代码,该库/框架期望您的代码异步执行。

您可以将同步代码转换为异步代码,但反之则不行。因此,一些执行您编写的代码(作为委托)的库可能要求您的代码是异步的以支持异步用例。一些库尝试对此进行智能处理并根据您的返回类型进行调整,但并非所有库都如此智能。

【讨论】:

  • 所以基本上,在 Promise 中包装 while 循环所做的一切就是使其异步,将其推送到事件循环,以便其余代码可以执行,完成后,调用堆栈中的 Promise 将按照它们被压入堆栈的顺序执行?
  • 在本视频的 12:16,Philip 谈到了拥有自己的线程的 Web API,这将允许这些 API 的并行执行,因为它们与调用位于不同的线程上堆?我想这对于 Node.js API 来说是一样的。他们会使用 C++ 和他们自己的线程。 youtube.com/watch?v=8aGhZQkoFbQ
  • 本地代码可以做你的 Javascript 不能做的事情。尽管它采用何种方法,但它是特定于实现的,并且通常被认为是一个黑匣子。 NodeJS api 与 web api 不同,因为它必须提供用于编写​​应用程序的 API,而不仅仅是 web 应用程序。对我来说突出的一个显着区别是 NodeJS 公开了异步方法,而我想不出一个不同步的 web api。
猜你喜欢
  • 2018-12-07
  • 2020-03-25
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多