【问题标题】:nodeJS design pattern to break out of a async.waterfall or promise.then.then [duplicate]nodeJS设计模式打破async.waterfall或promise.then.then [重复]
【发布时间】:2015-11-12 11:18:11
【问题描述】:

我有 4 个异步函数可以在我的节点应用程序中以瀑布样式执行。

async.waterfall 会整理它,但根据第一个函数的结果,我要么想出错,要么继续瀑布,要么突破到完成的函数。

目前没有办法做到这一点(除了带有成功值的“错误”,它只是闻起来很糟糕)。

我正在考虑使用 Promise,(Bluebird),但同样,我看不到突破的方法,如果我不在 .then 中返回另一个 Promise,那么下面的所有 .thens被执行,但参数为空。

还有其他可以提供帮助的模式/实用程序吗?

还是我想多了,只是正常调用第一个方法,然后根据结果运行async.waterfall,或者返回结果!

假设我有 4 个函数要调用,a,b,c,d.....

async.waterfall([
   function(cb) {
       a("some data", cb)
   },
   function(data, cb) {
        if(data) {
            // HERE we want to skip the remaining waterfall a go to the final func
         } else {
            b("some data", cb);
         }
   },
   c,
   d
],

function(err, data) {
    //do something 
 });

或者如果它们是承诺......

a("some data")
.then(function(data) {
    if(data) { 
        // here I want to stop executing the rest of the promises...
    } else {
       return b("some data")
    }
})
.then(c)
.then(d)
.catch(function(err) {
    //log error
})
.finally(function() {
     // do something
})

我想我应该这样做......

function doit(data, done) {
    a("some data", function(err, data) {
       if(err) { return done(err) };
       if(data) { return done(null, data) };

       //Here we run the waterfall if the above doesn't exist.

       async.waterfall([
           function(cb) {
               b("some data", cb)
           },
           c,
           d
        ],
        function(err, data) {
           done(err, data);
        });
}

【问题讨论】:

  • 我认为用一些特定的参数调用cb 会产生这种效果。但我认为这会将代码引向错误分支。
  • 是的,你可以做cb("success", data)之类的事情,然后在最终函数中检查err=="success",但这不是一个非常干净的解决方案......

标签: javascript node.js design-patterns asynchronous bluebird


【解决方案1】:

有了promise,你可以将'followup promises'附加到你需要的执行分支上:

a("some data")
.then(function(data) {
    if(data) { 
        return "foo";//other promises won't be executed here
    } else {
       return b("some data").then(c).then(d)
    }
})
.catch(function(err) {
    //log error
})
.finally(function() {
     // do something
})

【讨论】:

  • 啊哈!只见树木不见森林!谢谢。
  • @MattBryson 不客气。或者,您可以像在您的问题中那样链接承诺,并在处理程序中检查是否有任何参数传递给它,如果没有,只需调用return
猜你喜欢
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多