JavaScript 中的异步函数递归和 Bluebird Promises

Recursion with Asynchronous Functions and Bluebird Promises in JavaScript

在JavaScript中,我有四组函数:

Set_A
  synchronousFunction_One
  synchronousFunction_Two
  synchronousFunction_Three
  synchronousFunction_Four
  synchronousFunction_Five

Set_B
   objectA.asynchronousFunction_One
   objectA.asynchronousFunction_Two
                       .
                       .
                       .
   objectA.asynchronousFunction_N

Set_C
   objectA.asynchronousFunction_Three
   objectA.asynchronousFunction_Four
                       .
                       .
                       .
   objectA.asynchronousFunction_M

Set_D
  synchronousFunction_Six

我需要每个集合 运行 一个接一个,按照特定的顺序并有一定的限制:

  1. None Set_A 中的函数可以被调用,直到外部提供的承诺解决
  2. 迭代Set_A中的同步函数,每个调用一次
  3. 每次调用 Set_A 中的函数后,迭代器暂停并等待下面的第 4 步和第 5 步解决,然后再移至 Set_A[=34= 中的下一个元素]
  4. Set_B 被迭代,每个方法被调用一次,打开几个异步连接到互联网
  5. 一旦步骤 4 中的所有调用都已解决,Set_C 将迭代并调用每个方法一次,再次打开多个异步连接到互联网
  6. 一旦第 5 步中的所有调用都已解决,上述第 1 步中的迭代器将移至 Set_A
  7. 中的下一个元素

所以,基本上我们在这里做的是等待一些外部承诺来解决,然后我们调用函数 "prime the pump",可以这么说。然后,我们迭代对象接口的一部分,即 "independent part"-- 可以随时调用的方法。然后,我们迭代该对象接口的另一部分,"the dependent part"(即依赖部分中的 none 方法将正确关闭,除非独立部分中的所有方法至少关闭一次)。最后,我们调用清理函数。完成后,我们从 Set_A 中的下一个元素重新开始并再次启动泵。

最高级别的抽象,再次使用 Bluebird Promise 库,如下所示:

function doAllTheThings( externalPromise ) {

  var Set_A, Set_B, Set_C; // Array<Function>

  return new Promise( promiseToDoAllTheThings );
  function promiseToDoAllTheThings( resolve, reject ) {

    externalPromise.then( go );

    function go() {

      var primePump = Set_A.pop();
      if ( !primePump ) return;

      primePump();
      callEverythingInSet_B()
        .then( callEverythingInSet_C )
        .then( cleanUp )
      ;
    }

    function callEverythingInSet_B() {

      var promises = [];
      for ( var index in Set_B )
        promises.push( Set_B[index]() );
      return Promise.all( promises );
    }

    function callEverythingInSet_C() {

      var promises = [];
      for ( var index in Set_C )
        promises.push( Set_C[index]() );
      return Promise.all( promises );
    }

    function cleanUp() {

      // Do stuff
      go();
    }
  }
}

我真的很难过;昨天我花了几个小时进行分解和重构,每次都没有得到我预期的行为。我仍在编写我的实际代码;所以也许我会找到让我发疯的奇怪分号或类似的东西。

但与此同时,我想我应该 post 在这里问问——我对 Bluebird Promise Library 的理解是否正确?鉴于上面的代码,人们是否应该期待我所描述的行为?如果没有——你能提供一些演示代码吗?

我的毛囊谢谢你。

是的,这似乎有效。但是,一些提示:

  • 不要将 go() 函数的调用放在 cleanUp 中。将它链接在 go 函数本身的 .then(cleanUp) 之后,使递归性质显而易见(并保持本地引用)。
  • 那个

    return new Promise( promiseToDoAllTheThings );
    function promiseToDoAllTheThings( resolve, reject ) {
    

    错了。返回的承诺永远不会被解决或拒绝,您不使用这些回调。不过,你连shouldn't use them here都没有。省略那个promiseToDoAllTheThings,只做一个

     return externalPromise.then( go );
    

    直接。

  • 而不是那些普通的 for 循环,尝试使用 Array::map,它看起来会更好:-)
  • 您可以使用 Promise.each 而不是 go 循环