【问题标题】:How to know when a recursive, asynchronous task finishes如何知道递归异步任务何时完成
【发布时间】:2014-04-07 09:37:12
【问题描述】:

我有一个异步函数,它可以递归到自身。

每次函数运行时,我都会将 jQuery 延迟添加到数组中,并使用 $.when() 检查是否所有承诺都已解决。我的问题是,如果没有任意超时,我似乎无法执行此操作,因为我根本不知道函数何时停止递归并添加新的 Promise。

【问题讨论】:

  • 可能是我想多了,用setTimeout/clearTimeout可以解决,不过我还是对其他方法感兴趣。
  • 函数本身是否知道何时完成?您可以在开始时将 recursionComplete 延迟添加到数组中,并且仅在完成后解决。
  • 不,该函数不知道何时完成。它读取文件系统树并且总是可以遇到新的目录/文件。
  • 您知道何时将您的最后一个promise 添加到promises 吗?如果是这样,您就不能从那时开始开始检查吗,like this?
  • 你有没有想过在任务之后使用回调?

标签: javascript jquery asynchronous promise deferred


【解决方案1】:

仅同步推送到promises,以便您知道何时完成。由于您的函数是递归的并返回一个承诺,因此您可以只使用递归调用的结果承诺。仅将$.when() 用于当前 递归级别的结果,而不用于调用堆栈中的所有承诺。

还请查看我对Understanding promises in node.js for recursive function 和Is there an example of using raw Q promise library with node to recursively traverse a directory asynchronously? 的回答——即使他们没有使用jQuery 的实现,他们也应该让你知道如何去做。

【讨论】:

  • +1 这听起来是正确的想法。值得一提的是,promise 已经通过设计递归展开,因此可以简单地执行 this.then(function(){ /* actual calc creating kids */ return $.when.apply(children); })
  • 是的,虽然这里甚至不需要“递归”,但“展开”很重要:-)
  • It's done。对每个递归进行不同层次的思考是帮助我理解这一点的关键!
【解决方案2】:

只是补充一下 Bergi 所说的内容,并澄清根本问题:

没有办法知道什么时候没有更多的承诺会被链接到.then 的承诺。就像无法从函数中知道它返回的位置一样:

myPromise().then(function(vale){
        // I have no easy way to know when handlers will no longer be added to myPromise
        // from myPromise itself
});

就像:

 function mySynchronousFunction(){
      // I can't easily tell from here where this code returns or how many time it will
      // be called in the entire program lifecycle.
 };

您将如何使用同步代码解决这个问题?你可能一开始就不会拥有它。你会知道不要依赖全局程序状态和函数内部的调用者:)

类似于承诺。您不依赖最后一个处理程序何时添加到 Promise 代码中。

相反,您要做的是在您的实际示例中调用.forEach 内的内部承诺上的$.when,这将在它们全部完成时给您一个钩子,并且只有在它们完成时才依次解决它们内部承诺解决 - 这只是返回它们,因为承诺递归地展开。

除了 Bergi 的所有样本都很好 - 请参阅 Petka's implementation,这应该会给你一个大致的想法:)

祝你好运。


附带说明 - 你根本没有真正使用承诺作为承诺。您更多地将它们用作回调。如果你想让一个承诺等待另一个承诺完成,你可以使用.then:

promiseReturning1().then(promiseReturning2).then(promiseReturning3).then(function(lastResult){
       // all done here
});

而不是实现自己的异步队列。

【讨论】:

  • 另一个类比:不断变化的 Promise 引用就像一个装箱的变量(其中单个 Promise 是一个装箱的 值)。在同步代码中——你有一个变量,程序中有多个地方可以访问它——没有明显的方法可以知道程序中什么时候没有人会改变变量的值——这是你协调它的责任。很难在同步代码中使用全局变量这一事实实际上是全局变量的问题。
  • 谢谢,稍后我会看看这些答案。我昨天才开始尝试 Promises,所以我还有很多东西要学:)
  • @silverwind 慢慢来,欢迎来到更美好的未来 :)
猜你喜欢
  • 1970-01-01
  • 2021-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多