【问题标题】:Nodejs parallel async call, but with priorityNodejs并行异步调用,但优先
【发布时间】:2014-09-12 08:53:21
【问题描述】:

假设我使用 Node.js 尝试运行两个异步调用以获得一些答案。我知道有一个异步包,你可以在其中传递两个函数和一个可选的回调。

async.parallel([fun1(){callback(null,1);},
fun2(){callback(null,2);}],
function(err, results) {  
});

但是假设我现在有一个优先级,如果fun1返回一个值,那么我不需要fun2的回答,只有fun1返回null,然后我等待fun2。所以我不想使用回调函数,因为回调要等待两个函数完成,而 fun2 可能需要很长时间。

现在我只是使用一种非常详尽的方式,为两个异步调用创建回调函数。

function(){
    var theAnswer,FromFun1,FromFun2;
    var reply1,reply2;
    fun1(reply1="answered";FromFun1=1;complete());
    fun2(reply2="answered";FromFun2=2;complete());
   function complete(answer){
      if(reply1=="answered"){
           theAnswer=FromFun1;
      }else if(reply1==null){
           // Don't do anything because fun1 is not finished running. 
       }else if(reply2=="answered"){
           theAnswer=FromFun2;
       }else{
           // Both have no answer, err.
       }
   }
}

有没有更好的方法来做到这一点?

【问题讨论】:

  • 您应该尝试使用 Promise。就像var second = fun2(); return fun1().then(function(r) { return r || second; }) 一样简单
  • 感谢 Bergi,这很有帮助。我会投票给你:)
  • 谢谢@Bergi,这很有帮助。我会投票给你:)。我还有一个问题。在 then() 中,它要么返回 r,即答案,要么返回 'second',即承诺。接下来我该如何处理?
  • 如果你返回答案,它将使用它,如果你从then返回一个承诺,它会等待那个。这就是then 的意义所在:-)

标签: javascript node.js asynchronous parallels


【解决方案1】:

最好使用瀑布而不是并行执行,因为您可以将上一个函数的结果作为参数传递给下一个函数。

async.waterfall([
function(callback){
    callback(null, 'one');
},
function(arg1, callback){

    // arg1 now equals 'one'
   if(arg1==null){
   // it will not take time it returns immediately 
    callback(null, 'done');

    }else{
    // do your another stuff here fun2 logic here 
    // it will not be executed and so it dont take time 
      }
  }
  ], function (err, result) {
  // result now equals 'done'    
}); 

【讨论】:

  • 这是否意味着瀑布中的功能是顺序的?
  • 是的,它们是连续的,但它们不会花费太多时间
  • OP 的好处是可以并行运行这两个函数;这应该好处应该被使用。瀑布是连续发生的,所以虽然这是一个优雅的解决方案,但并不是完全最优的。
  • @zamnuts 我知道它不是最佳解决方案,但正如 OP 所述,第二个函数的执行取决于第一个函数的输出,所以我认为这不能并行完成。
  • @VivekBajpai 如果在任何一个函数返回有效结果后,它可以取消/中止剩余的挂起函数,但这取决于内部发生的事情(例如带有套接字的事情)。
【解决方案2】:

我在这个场景中使用的技巧是在回调的第一个参数中返回“done”:

async.parallel([
  function(callback){
    callback("done",1);
  },
  function(callback){
    callback(null,2);
  }
], function(err, results) { 
  console.log(err, results);   // done [ 1 ] or done [ 1 , 2 ] 
});

听起来像是一种 hack,我通常不这样做,但在一些罕见的情况下,例如这种情况,它实际上可以保持代码干净......只需将其记录下来,以便其他人知道你的意图是什么。

【讨论】:

  • 对控制流使用异常,尤其是快捷异步函数,是一个聪明的技巧:-)
猜你喜欢
  • 2014-11-26
  • 2017-05-27
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
  • 2017-05-15
相关资源
最近更新 更多