检测某个功能启动的所有异步工作何时完成

时间:2019-03-28 21:27:49

标签: javascript asynchronous promise

我需要知道函数调用启动的所有工作何时完成。

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

function outer(inner) {
   inner()
}

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

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

我知道Promise.all的工作方式。但是对于Promise.all,您需要传递一系列承诺。我希望我的函数不了解内部函数内部发生的细节。由于javascript通过回调而不是Promise处理大量异步行为,因此Promise.all无法处理每种异步工作情况。

从外部函数的范围来看,是否有任何方法可以检测内部函数的异步和同步工作是否完成,并且这种行为是否适用于我传递给outer的任何函数?

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

我正在努力避免将其硬编码到内部函数中,因为这样会打消构建更高阶函数来处理allWorkComplete事件的意义。

这只是JavaScript中的反模式吗?

1 个答案:

答案 0 :(得分:3)

  

我希望我的函数不了解内部函数内部发生的细节。

那不可能 [1]
内部功能需要配合并告诉您完成的时间-通常,它会通过返回适当的承诺来做到这一点。

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

  

这只是JavaScript中的反模式吗?

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

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

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

(免责声明:上面的代码并不是一个很好的承诺代码-您不应该经常使用new Promise,仅在包装了特定异步调用但不执行其他任何操作的辅助函数中使用-应该给您和想法如何在这里使用诺言