Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中异步函数和Bluebird承诺的递归_Javascript_Recursion_Iteration_Promise_Bluebird - Fatal编程技术网

JavaScript中异步函数和Bluebird承诺的递归

JavaScript中异步函数和Bluebird承诺的递归,javascript,recursion,iteration,promise,bluebird,Javascript,Recursion,Iteration,Promise,Bluebird,在JavaScript中,我有四组函数: Set_A synchronousFunction_One synchronousFunction_Two synchronousFunction_Three synchronousFunction_Four synchronousFunction_Five Set_B objectA.asynchronousFunction_One objectA.asynchronousFunction_Two

在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
我需要以特定顺序和特定约束逐个运行每个集合:

  • 在外部提供的承诺解决之前,集合_A中的任何函数都不能调用
  • 集合_A中的同步函数被迭代,每次调用一次
  • 每次调用集合_a中的函数后,迭代器都会暂停并等待下面的步骤4和步骤5进行解析,然后再转到集合_a中的下一个元素
  • 对Set_B进行迭代,每个方法调用一次,打开几个到internet的异步连接
  • 一旦第4步中的所有调用都已解决,将迭代Set_C,并再次调用每个方法,再次打开到internet的几个异步连接
  • 一旦解决了步骤5中的所有调用,上面步骤1中的迭代器将转到集合A中的下一个元素
  • 因此,我们在这里所做的基本上是等待一些外部承诺得到解决,然后我们调用一个函数来“给泵充注”,可以这么说。然后,我们迭代对象接口的一部分,即“独立部分”——可以随时调用的方法。然后,我们迭代该对象接口的另一部分,“依赖部分”(即,除非独立部分中的所有方法至少关闭一次,否则依赖部分中的任何方法都不会正确关闭)。最后,我们调用cleanup函数。完成后,我们从集合_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();
        }
      }
    }
    
    函数完成所有任务(外部承诺){
    var Set_A,Set_B,Set_C;//数组
    归还新的承诺(承诺完成所有事项);
    功能承诺完成所有事项(解决、拒绝){
    外部承诺。然后(去);
    函数go(){
    var primePump=Set_A.pop();
    如果(!泵)返回;
    预充泵();
    CallerythingSet_B()
    。然后(调用所有设置_C)
    .然后(清理)
    ;
    }
    函数调用方ythingset_B(){
    var承诺=[];
    for(集合B中的var指数)
    promises.push(Set_B[index]());
    返回承诺。全部(承诺);
    }
    函数调用方ythingset_C(){
    var承诺=[];
    for(集合C中的var指数)
    promises.push(Set_C[index]());
    返回承诺。全部(承诺);
    }
    函数清理(){
    //做事
    go();
    }
    }
    }
    
    我真的很难接受这个;昨天我花了几个小时分解和重构,每次都没有达到我预期的效果。我仍在编写我的实际代码;也许我会找到让我发疯的奇怪分号之类的东西

    但与此同时,我想我会把这篇文章贴在这里,然后问——我对蓝鸟承诺图书馆的理解正确吗?考虑到上面的代码,人们应该期待我描述的行为吗?如果没有,你能提供一些演示代码吗


    我的毛囊谢谢你。

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

    • 不要将对
      go()
      函数的调用放在
      cleanUp
      中。将其链接到
      之后。然后(清理)
      go
      函数本身中,使递归性质变得明显(并保持引用的局部性)
    • return new Promise( promiseToDoAllTheThings );
      function promiseToDoAllTheThings( resolve, reject ) {
      
      这是错误的。返回的承诺永远不会被解决或拒绝,您不会使用这些回调。然而,你甚至连一点都没有。只需忽略承诺做所有事情的
      ,而只做一件事

       return externalPromise.then( go );
      
      直接的

    • 尝试使用,而不是那些简单的
      for
      循环,它会看起来更好:-)
    • 您可以使用而不是
      go
      循环

    伯吉获胜!谢谢你,伙计。你和蓝鸟有联系吗?我到处都能看到你,伙计。(我现在正在一支代码笔中输入所有这些内容;一旦准备好,将链接给后代。)还有——你知道哪一种性能更好吗,vanillaforArray::map?这是服务器端的代码,所以我试图坚持使用最快的代码。(因此,选择蓝鸟。)不,@BenjaminGruenbaum和@Esailija是蓝鸟的作者,我还没有为它做出贡献,但我只致力于我自己的(学术)承诺的实现。。然而,这是一个微观优化,旨在实现干净的代码。网络连接是限制方法性能的因素。下面是@Bergi建议的主要修订版本的CodePen模型:工作非常出色!谢谢,伙计!