【问题标题】:Detect when all async work initiated by a function is complete检测函数启动的所有异步工作何时完成
【发布时间】:2019-03-29 05:42:57
【问题描述】:

我需要知道由函数调用发起的所有工作何时完成。

我有一个函数,它将另一个函数作为参数并调用该函数:

function outer(inner) {
   inner()
}

内部函数可能会启动一些异步行为:

function inner() {
   new Promise(...)
   new Promise(...)
   new Promise(...)
   requestAnimationFrame(...)
   requestAnimationFrame(...)
}

我知道Promise.all 的工作原理。但是对于 Promise.all,你需要传递一系列的 Promise。我希望我的函数不知道内部函数内部发生的细节。由于 javascript 使用回调而不是 Promise 处理大量异步行为,因此 Promise.all 无法处理所有异步工作情况。

从外层函数的范围来看,有没有办法检测内层函数的异步和同步工作是否完成,以及这个行为是否适用于我传入outer的任何函数?

function outer(inner) {
   inner.allWorkComplete(() => ...do more work)
   inner();
}

我试图避免将其硬编码到内部函数中,因为这违背了构建更高阶函数来处理 allWorkComplete 事件的意义。

这只是 javascript 中的反模式吗?

【问题讨论】:

  • 没有。 Promise.all 完全不同。
  • Promise.allPromise.all 究竟有何不同?
  • @JeremyGottfried 你的问题是描述 Promise.all,使用它有什么问题?
  • 这个想法是,我想知道函数的工作何时完成,而不是简单地传递一组承诺。范围不同。例如,requestAnimationFrame 在技术上不是一个承诺,但它是异步的。

标签: javascript asynchronous promise


【解决方案1】:

我希望我的函数不知道内部函数内部发生的细节。

这是不可能的[1]
内部函数需要合作并告诉您何时完成 - 通常,它通过返回适当的承诺来完成。

1: 至少不是没有很多努力。您需要控制整个环境,以便检测何时调用任何异步原语。

这只是 javascript 中的反模式吗?

是的。执行任何异步工作的函数要么需要自己处理完成(如果其他人不感兴趣),要么提供一种方法来监听它。

在您的示例中,这意味着 creating promises for the requestAnimationFrame calls,然后将所有承诺与 Promise.all 组合以返回一个承诺,该承诺会在您的内部函数完成其任务时解决:

function inner() {
  return Promise.all([
    new Promise(...),
    new Promise(...),
    new Promise(...),
    new Promise(resolve => {
      requestAnimationFrame(() => {
        ...
        resolve();
      })
    }),
    new Promise(resolve => {
      requestAnimationFrame(() => {
        ...
        resolve();
      })
    }),
  ]);
}

(免责声明:以上不是很好的承诺代码——你不应该经常使用new Promise,只能在包装特定异步调用但不做任何其他事情的辅助函数中使用——但应该让你了解如何承诺可以在这里使用)

【讨论】:

  • 感谢您认真对待我的问题并花时间回答。我很感激。当我在这个网站上提问时,我觉得有一种假设是我不知道我在说什么,而实际上我只是好奇并且无法在其他地方找到答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-27
  • 2016-02-19
  • 2020-09-07
  • 2020-01-04
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
相关资源
最近更新 更多