【问题标题】:Asyncjs : Bypass a function in a waterfall chainAsyncjs:绕过瀑布链中的函数
【发布时间】:2013-03-03 10:28:25
【问题描述】:

我想在nodejs 中使用asyncjs 从瀑布函数链中跳转一个函数。

我的代码如下所示:

async.waterfall([
    function(next){
        if(myBool){
            next(null);
        }else{
            // Bypass the 2nd function
        }
    },

    // I want to bypass this method if myBool is false in the 1st function
    function(next){
    },

    // Always called
    function(next){
    }
]);

你知道不使用 put 的正确方法吗:

if(!myBool){
    return next();
}

在我要绕过的函数中。

谢谢!

【问题讨论】:

    标签: node.js asynchronous callback waterfall


    【解决方案1】:

    另一种可能是:

    var tasks = [f1];
    
    if(myBool){
        tasks.push(f2);
    }
    
    tasks.push(f3);
    
    async.waterfall(tasks, function(err, result){
    });
    

    其中f1f2f3 是您的函数。

    除此之外,你最好明确地这样做,避免让你的代码过于复杂,通常越简单越好

    更新:

    function f1(done){
        if(myBool){
            f2(done);
        }else{
            done();
        }
    }
    
    function f2(done){
        async.nextTick(function(){
            // stuff
            done();
        });
    }
    
    async.waterfall([f1,f3],function(err,result){
        // foo
    });
    

    【讨论】:

    • 感谢您的回答。但是如果在瀑布过程中 f1 函数中设置了 myBool 呢?
    • 在这种情况下,我要么将f2 拉入f1(我会更新),要么就像你提到的那样使用f2 中的条件(你想避免的替代方案)
    【解决方案2】:

    我认为这应该可行:

    var finalCallback = function(err, result){
      if(err)
         // handle error..
      else
         console.log('end! :D');
    }
    
    async.waterfall(
      [
        function step1(callback){
           // stuff
           callback(null, someData);
        },
        function step2(someData, callback){
           if(skip_step_3)
              finalCallback(null, someData);
           else
              callback(null, someData);
        },
        function step3(moreData, callback){
           // more stuff
           callback(null, moreData);
        }
      ],
      finalCallback
    )
    

    async 的创建者在 github repo (https://github.com/caolan/async/pull/85) 中推荐这个

    【讨论】:

      【解决方案3】:

      使用if-async 模块,您的代码将如下所示:

      var async = require('async')
      var ifAsync = require('if-async')
      
      async.waterfall([
          foo,
          ifAsync(p1).then(c1).else(c2),
          bar
      ], function(err) {})
      

      完整示例请看这里:https://github.com/kessler/if-async#example-2-using-with-asyncjs-waterfall

      【讨论】:

        【解决方案4】:

        我来晚了,但async-if-else 可能会帮助你。

        示例代码

         var async = require('async-if-else')(require('async'));
        
          function emailExists(user, callback) {
            user.find(user.email, function(err, dbUser){
              if (err)
                return callback(error);
        
              if(!dbUser)
             return callback(null, false); // does not exist, predicate will be false 
        
           callback(null, true);  
          });
          }
        
          function updateAccount(user, callback) { 
            user.update( ..., callback);
          }
        
          function importFromLegacyByEmail(user, callback) { 
            remoteClient.get(user, callback);
          }
        
          async.waterfall([
            async.constant({email: 'thiago@email.com', dogs: 2, money: 0, fun: 100 }),
            async.if(emailExists, updateAccount).else(importFromLegacyByEmail),
            sendEmail
          ], handler);
        

        【讨论】:

          【解决方案5】:

          我会推荐使用clojurescript,它有一个很棒的core-async 库,在处理异步调用时让生活变得超级简单。

          在你的情况下,你会这样写:

          (go
            (when-let [res1 (<! (asyncFunc1))]
              (<! (asyncFunc2 res1)))
            (<! (asyncFunc3)))
          

          注意go 宏会导致主体异步运行,&lt;! 函数会阻塞直到异步函数返回。

          代码将首先阻塞第一个异步函数。然后,如果结果为真,它也会在块上运行第二个异步函数。最后,它将运行第三个异步函数并阻止它。

          【讨论】:

            猜你喜欢
            • 2017-03-27
            • 2019-04-05
            • 2023-03-15
            • 2014-05-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多