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

Recursion with Asynchronous Functions and Bluebird Promises in JavaScript

本文关键字:Bluebird Promises 递归 函数 异步 JavaScript      更新时间:2023-09-26

在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. 在外部提供的promise解析之前,不能调用Set_A中的任何函数
  2. Set_A中的同步函数被迭代,每个调用一次
  3. 每次调用Set_a中的函数后,迭代器都会暂停并等待下面的步骤4和步骤5进行解析,然后再转到Set_a的下一个元素
  4. Set_B被迭代,每个方法被调用一次,打开几个到互联网的异步连接
  5. 一旦解决了步骤4中的所有调用,Set_C就会被迭代,每个方法都会被调用一次,再次打开与互联网的几个异步连接
  6. 一旦解决了步骤5中的所有调用,上面步骤1中的迭代器就移到Set_A中的下一个元素

因此,本质上,我们在这里所做的是等待一些外部承诺得到解决,然后我们称之为"启动泵"的函数。然后,我们迭代对象接口的一部分,即"独立部分"——可以随时调用的方法。然后,我们迭代该对象接口的另一部分,"依赖部分"(即,除非独立部分中的所有方法至少关闭一次,否则依赖部分中的任何方法都不会正确关闭)。最后,我们调用cleanup函数。完成后,我们从Set_A中的下一个元素开始,再次启动泵。

最高级别的抽象,再次使用Bluebird Promise Library,看起来是这样的:

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();
    }
  }
}

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

但与此同时,我想我应该把这个贴在这里,然后问——我对蓝鸟承诺图书馆的理解正确吗?给定上面的代码,是否应该期待我所描述的行为?如果没有,你能提供一些演示代码吗?

我的卵泡谢谢你。

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

  • 不要将对go()函数的调用放在cleanUp中。在go函数本身的.then(cleanUp)之后将其链接起来,使递归特性显而易见(并保持引用的本地性)
  • return new Promise( promiseToDoAllTheThings );
    function promiseToDoAllTheThings( resolve, reject ) {
    

    是错误的。返回的承诺永远不会被解决或拒绝,您不会使用这些回调。然而,你甚至不应该在这里使用它们。只需省略promiseToDoAllTheThings,只执行

     return externalPromise.then( go );
    

    直接。

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