Async: 在不抛出错误的情况下打破瀑布链

创建于 2011-02-15  ·  8评论  ·  资料来源: caolan/async

有人告诉我,我需要重构使用异步瀑布的代码。 我使用它主要是因为我有几个链接的函数太深了,我想重用一个函数,等等。在链的某一点有一个条件不是严格的错误条件,但我没有想要传递瀑布链的其余部分,因为它没有用 - 例如我做了一个查询并且没有结果,这不是一个错误,我不想一直向下传播而没有结果。 如果我在没有异步的情况下执行此操作,我想我会有一个“最终”回调,并且可以调用它以脱离链而不会显式抛出错误。 瀑布中似乎不存在此功能。 有没有办法干净地做到这一点? 我能看到的唯一方法是抛出一个特殊错误,然后在最终回调中处理它以返回一个非错误。

最有用的评论

我个人发现自己需要这样的功能,并认为应该将其添加到核心库中。

如果有人感兴趣,这是我的帮手解决方法...

exports.breakWaterfall = function(tasks, callback){
    async.waterfall(tasks, function(){
        if(arguments[0] === 'break'){
            arguments[0] = null;
        }
        callback.apply(null, arguments);
    });
}

如果您需要中断到任务中的最后一个函数,只需像这样调用回调: done('break', other, arguments);

帮助程序仅检测'break'并改变参数,因此对于您的其余代码而言,它看起来不像是错误。

所有8条评论

你好,

你现在可能已经解决了你的问题,顺便说一句,这是我的方法:

var flow = [
    async.apply(...),
    // ...
];

async.waterfall(flow, function (err) {
    if (err === 'ok') return;
    // handle error
});

当函数使用err = 'ok'调用回调时,瀑布的最终回调会拦截它。

我有一个类似的问题,我正在添加一个回调包装器(我可以避免)只是为了检查我使用的每个瀑布是否有错误。 当有不止一个瀑布时,它就不那么干净了。
回调函数本身是否可以有另一个名为“final”的属性,人们可以调用它来结束。
就像是

function search (cond, callback) {
  async.waterfall([function (cb) {
      db.get(cond, cb);
    },
    function (res, cb) {
      if (!res || !res.length)
        return cb.final();
      //do something useful
    }
  ], callback);
}

我不必包装回调,它可以链接到程序的其余部分。

@caolan对于@jnordberg拉取请求,您有什么不喜欢的吗? 如果是这样,我可以做些什么来让这个拉取请求被接受?

@tax :实际上我发现我们可以通过像这样传递 'error' = true 来跳到最终函数:

async.waterfall([函数(回调){
回调(空); // <--- 转到下一个 fn
},
功能(回调){
回调(真); // <--- 跳到最后一个 fn
},
功能(回调){
回调(空); // <--- 这个 fn 不会被调用
}
], 打回来);

@tot2ivn感谢您的提示!

如果您设置错误,结果将为空。

var async = require('async');

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

  function( callback ){
    console.log('two');
    callback( true, 'more info' );
  },

  function( callback ){
    console.log('three');
    callback( null );
  }
], function(err, result){
  console.log( err, result );
} );

// RESULT
// one
// two
// true undefined

根据@caolan对关闭拉取请求 #85 的评论,这个问题可能应该被关闭

我个人发现自己需要这样的功能,并认为应该将其添加到核心库中。

如果有人感兴趣,这是我的帮手解决方法...

exports.breakWaterfall = function(tasks, callback){
    async.waterfall(tasks, function(){
        if(arguments[0] === 'break'){
            arguments[0] = null;
        }
        callback.apply(null, arguments);
    });
}

如果您需要中断到任务中的最后一个函数,只需像这样调用回调: done('break', other, arguments);

帮助程序仅检测'break'并改变参数,因此对于您的其余代码而言,它看起来不像是错误。

此页面是否有帮助?
0 / 5 - 0 等级