【问题标题】:Node.js: Asynchronous callback confusionNode.js:异步回调混淆
【发布时间】:2015-02-11 19:31:46
【问题描述】:

我正在尝试弄清楚如何为 Web 应用程序创建异步函数。我正在做一个数据库查询,将数据处理成更方便的格式,然后尝试将我的路由器设置为传回该文件。

//Module 1
//Module 1 has 2 functions, both are necessary to properly format
function fnA(param1){
    db.cypherQuery(query, function(err, result){
        if(err){
            return err;
        }
        var reformattedData = {};
        //code that begins storing re-formatted data in reformattedData

        //the function that handles the rest of the formatting
        fnB(param1, param2);
    });
});

function fnB(param1, reformattedData){
    db.cypherQuery(query, function(err, result){
        if(err){
            return err;
        }
        //the rest of the reformatting that uses bits from the second query 
        return reformattedData;
    });
});

exports.fnA = fnA;

然后在我的路由器文件中:

var db = require('module1');

router.get('/url', function(req,res,next){
    db.fnA(param1, function(err, result){
        if (err){
            return next(err);
        }
        res.send(result);
    });
});

当我尝试通过点击路由器指示的 URL 来测试它时,它只是无限期地加载。

我知道我上面的内容是错误的,因为我从未编写过需要回调的函数。但是,当我尝试弄清楚如何重写它时,我真的很困惑-如何编写函数以在其中发生异步内容时进行回调?

有人可以帮我重写我的函数以正确使用回调,这样当我实际使用该函数时,我仍然可以使用异步响应吗?

【问题讨论】:

    标签: javascript node.js asynchronous callback


    【解决方案1】:

    您使用路由器文件中的 db.fa,并将第二个参数作为回调函数传递。但是函数签名没有 cb 参数并且不使用它。

    主要思想 - 您尝试启动异步操作并且不知道它何时结束,因此您向它发送一个回调函数以在所有操作完成时触发。

    固定的代码应该是这样的:

    //Module 1
    //Module 1 has 2 functions, both are necessary to properly format
    function fnA(param1, cb1){
        db.cypherQuery(query, function(err, result){
            if(err){
                cb1(err); <-- return error to original call
            }
            var reformattedData = {};
            //code that begins storing re-formatted data in reformattedData
    
            //the function that handles the rest of the formatting
            fnB(param1, param2, cb1);
        });
    });
    
    function fnB(param1, reformattedData, cb1){
        db.cypherQuery(query, function(err, result){
            if(err){
                cb1(err); <-- return error to original call
            }
            //the rest of the reformatting that uses bits from the second query 
            cb1(false, dataObjectToSendBack); <--- This will call the anonymouse function in your router call
        });
    });
    
    exports.fnA = fnA;
    

    路由器文件:

    var db = require('module1');
    
    router.get('/url', function(req,res,next){
        db.fnA(param1, function(err, result){ <-- This anonymous function get triggered last 
            if (err){
                return next(err);
            }
            res.send(result);
        });
    });
    

    【讨论】:

    • return err 不正确,因为将其返回到您所在的位置将无济于事。您需要一种方法来告诉回调出现错误,因为现在,当出现错误时,您不会与外界进行任何通信。
    • @jfriend00 你是对的,那是 Dude 代码的复制粘贴。固定
    • 好的,现在这更有意义了。非常感谢本!只是为了确保我现在理解这一点,这是否意味着在路由器文件中调用 cb1 之前未定义它?通过代码显示: ...function(err, result){ if(err)...
    • @Dude 是的,它是一个匿名函数
    • @Ben,你太棒了!这个核心概念终于对我来说就位了,现在非常有意义。伙计,我喜欢这个地方。
    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2016-05-25
    • 2015-05-26
    • 2017-03-20
    • 2020-11-23
    • 2014-07-14
    • 1970-01-01
    • 2013-12-15
    相关资源
    最近更新 更多