【问题标题】:Skip to main callback with result in async waterfall node js跳到主回调并导致异步瀑布节点 js
【发布时间】:2015-12-29 16:22:53
【问题描述】:

我是 node js 的新手,正在使用异步瀑布。

var methods = function (req, res) {
async.waterfall([
    func1(req, res),
    func2,
    func3
], mainCallback);
};

app.get("/create", function(request, response)
{
  methods(request, response);    
});

function func1 (something, res, callback) {
    if(something == 0)
    {
     callback (null, res, somethingelse);
    }
    else
    {
     mainCallback("success");
     }

}

function func2 (something, res, callback) {        
      callback (null, res, somethingmore);        
}

function func3 (something, res, callback) {
      callback (null, res, somethingmore);
}

function mainCallback (error, success)
{
 if (error)
{
    console.log("error");
}

if(success)
{
    //console.log("success");
}

}

在上面的流程中,我可以跳到主回调,但不能向主回调发送更多参数。

例如,如果我想从主调用返回响应,那么如何将其作为 func1 的参数发送?

我在 func1 中尝试了以下方法,但没有成功

mainCallback("success", response)

请告诉我如何跳过方法 func2 和 func3。还将响应作为参数发送到 main allback。

【问题讨论】:

    标签: javascript node.js asynchronous


    【解决方案1】:

    不要使用返回/抛出错误来控制执行流程,这是代码异味。

    改为如下重构代码:

    function mainCallback(err, res) {
        if (err) {
            console.log(err);
        } else {
            console.log(res);
        }
    }
    
    function routeHandler(req, res) {
        func1(req, res, function(err, res) {
            if (res.something === 0) {
                async.waterfall([
                    func2,
                    func3
                ], mainCallback)
            } else {
                mainCallback(null, 'success')
            }
        })
    }
    
    app.get('/create', routeHandler());
    

    请注意,当调用mainCallback 时,我将第一个值作为null 传递,这样做是为了尊重错误协定,所以当调用 mainCallback 并且第一个参数有一个值时,我肯定知道这是一个错误,否则第二个参数应该包含结果。

    此外,这将使您的代码更具可读性和更易于理解,您在 func1 中有明确的 if 分支。

    我也建议阅读此内容:http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/

    【讨论】:

    • 感谢您的回复。实际上我已经补充说,如果只是例如。实际上是在每个回调中执行 DB 调用并决定要做什么.. 无论如何感谢链接.. 让我尝试在第二个参数中发送响应数据..
    【解决方案2】:

    跳过瀑布其余部分的唯一方法是传入 err 参数。

    因此调用:done({ something: { val: 1 }}) 将跳过瀑布的其余部分。

    如果它不是真正的错误,您可以将一些您将在最终回调中解析的对象作为错误,但它将作为结果回调中的第一个参数传递 (mainCallback)。

    function func1 (something, res, callback) {
        if (something == 0) {
            callback (null, res, somethingelse);
        } else {
            callback({val:1});
        }
    }
    

    编辑

    但是,是的,您不应该使用错误来控制流程或中断异步。它应该只用于传播错误。

    【讨论】:

    • 感谢您的最快回复。我在 func1 done({value:1});但它显示 done 没有定义..
    • @itdeeps 我使用done 作为回调参数名称的示例(通常使用的名称是:cbnextdonecallback)。我已经更新了答案。
    • 永远不要返回/抛出错误/异常来控制执行流程。
    • @EdinM 对不起我的错.. 我认为这是预定义的方法。好的,正如您和 nvartolomei 提到的,无法向主回调添加其他参数。好的,让我试试..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 2019-02-12
    相关资源
    最近更新 更多