Javascript 如何知道递归异步任务何时完成

Javascript 如何知道递归异步任务何时完成,javascript,jquery,asynchronous,promise,deferred,Javascript,Jquery,Asynchronous,Promise,Deferred,我有一个异步函数,它可以自己递归 每次函数运行时,我都会将jQuery延迟添加到数组中,使用$.when()检查是否所有承诺都已解决。我的问题是,如果没有一个任意超时,我似乎无法做到这一点,因为我根本不知道函数何时停止递归并添加新的承诺 这是一个例子 这是我的答案 只同步推送到承诺,以便您知道何时完成。因为您的函数是递归的,并且返回一个承诺,所以您可以只使用递归调用的结果承诺。仅对当前递归级别的结果使用$.when(),而不是调用堆栈中的所有承诺 还要检查我对和的回答-即使他们没有使用jQue

我有一个异步函数,它可以自己递归

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

  • 这是一个例子
  • 这是我的答案

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


还要检查我对和的回答-即使他们没有使用jQuery的实现,他们也应该给你一个如何实现的想法。

只是为了补充Bergi所说的,并澄清根本问题:

无法知道何时不再有承诺会被链接到带有
的承诺上。然后
。就像无法从函数中知道其返回的位置一样:

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.
 };
如何使用同步代码解决这个问题?你可能一开始就不会拥有它。您最好不要依赖全局程序状态和函数中的调用者:)

这类似于承诺。您不依赖于在承诺代码中添加最后一个处理程序的时间

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

除了Bergi的样品都很好之外,看看哪一个能让你大致了解:)

祝你好运


顺便说一下,你根本没有把承诺当作承诺。您更多地将它们用作回调。如果希望一个承诺等待另一个承诺完成,可以使用
。然后

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

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

也许我想得太多了,可以用setTimeout/clearTimeout解决,但我仍然对其他方法感兴趣。函数本身知道什么时候完成了吗?您可以在开始时向数组添加一个延迟的
recursionComplete
,并仅在完成时解析。不,函数不知道何时完成。它读取一个文件系统树,并且总是会遇到新的目录/文件。您知道在何时将上一个
promise
添加到
promises
?如果是这样,你就不能从那一点开始检查吗?你是否想过在任务完成后使用回调?+1这听起来是正确的想法。值得一提的是,承诺已经通过设计递归地展开,因此可以简单地执行
这项操作。然后(function(){/*react calc creating kids*/return$.when.apply(children);})
是的,虽然这里甚至不需要“递归地”展开,但是“展开”很重要:-)。对每个递归进行不同层次的思考是帮助我理解这一点的关键!另一个类比:变化的承诺引用类似于装箱变量(其中单个承诺是装箱值)。在同步代码中—您有一个变量,程序中有多个位置可以访问它—没有明显的方法可以知道程序中的任何人何时不再更改该变量的值—这是您协调该变量的责任。事实上,在同步代码中很难使用全局变量,这实际上就是全局变量的问题。我昨天才开始尝试承诺,所以我还有很多东西要学:)@silverwind慢慢来,欢迎来到更美好的未来:)