让express.js从异步回调发送响应

时间:2015-03-27 19:29:56

标签: node.js asynchronous express

我有一个非常简单的场景,Node / Express.js中的RESTful端点需要调用另一个REST服务并返回其结果。

我面临的问题是在Express方法中获取响应以发回适当的数据。

var express = require('express');
var app = express();

app.post('/test', function(req, res) {
    async.series([ function(callback) {
        var httpConfig = app.config.evaluateRuleService;
        logger.info("About to make request");
        // make an async call here
        require('../utils/http-wrapper/http').post(req.body, httpConfig,
                function(err, data) {
                    logger.info("still have res: " + res);
                    logger.info("Got response: " + data);
                    // data.isAuthorized is set by the service being invoked
                    callback(false, data);
                });
    } ],
    function(err, results) {
        logger.info("Inside collate method");
        // correctly gets invoked after async call completes
        // but res.json isn't sending anything to the client
        res.json({
            authorized : results.isAuthorized
        });
    })
    // Problem: The client is receiving the response before the async call completes
});

这里是日志输出:

"Listening on port 8897","time":"2015-03-27T19:22:24.435Z","v":0}
"About to make request","time":"2015-03-27T19:22:30.608Z","v":0}
fetch() POST http://localhost:8897/test 
**<logs of the server method being invoked are printed out>** 
"still have res: [object Object]","time":"2015-03-27T19:22:30.616Z","v":0} 
"Got response: {\"isAuthorized\":true}","time":"2015-03-27T19:22:30.616Z","v":0}
"Inside collate method","time":"2015-03-27T19:22:30.617Z","v":0}

因此,顺序以令人愉快的方式发生,但是,调用此端点的客户端看到返回的结果为空,而不是我尝试发送到响应中的预期authorized : results.isAuthorized最后的回调。

非常感谢

使用解决方案进行编辑:

正如彼得和凯文指出的那样,有两个问题正在发生,而且认为反应过早发送是一种误诊。

results对象确实是一个数组,我的相关索引是[0]。然后我需要将String response转换为JSON对象,以便能够访问我需要的字段。

解决此问题的回调函数的答案是:

function(err, results) {
    logger.info('Inside collate method');
    // Need to access array at appropriate index 
    logger.info('Authorize Response: ' + results[0]);
    // Need to parse the value at index 0 as a JSON object
    var authorizeResponse = JSON.parse(results[0]);
    res.json({
            authorized : authorizeResponse.isAuthorized
        });
}

1 个答案:

答案 0 :(得分:2)

您没有async.series的正确签名。最终回调的参数是error, arrayOfResults,因此您需要results[0].isAuthorized才能获得正确的值。我的理论是您的代码生成对象{isAuthorized: undefined},因为结果数组没有isAuthorized属性。然后将其序列化为JSON中的空对象,如下所示:

> JSON.stringify({isAuthorized: undefined})
'{}'

然而,时间和控制流程正常。问题不在于过早发送响应。