在node.js / express.js中从多个异步源构建对象

时间:2014-08-16 21:13:59

标签: javascript json node.js asynchronous express

我很难在网上找到解决问题的方法,希望有人在这里帮助我。我有一个快速路由,为不同的JSON对象执行一些API请求。我想为我的客户端视图构建一个JSON响应,但到目前为止我的所有尝试都会产生先前的请求数据或根本没有数据。

所以我的问题是使用node / express js的JavaScript专家。如何将多个JSON对象源同步到一个单个对象中,以便在一个响应中返回到客户端?你使用的是库还是一些回调魔法?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

Async是用于此目的的更受欢迎的库之一。还有许多其他异步和承诺库可以帮助解决这个问题。根据您的需要,有不同的方法具有不同的行为。我认为系列方法是您所需要的,但请仔细检查文档。

var async = require('async');
var request = require('request');


app.get('endpoint',function(req, res){
    async.series([
        function(callback){request.get('url',callback)},
        function(callback){request.get('url2',callback)},
        function(callback){request.get('url'3,callback)},  
    ],
    function(err,results){
        //handle error

        //results is an array of values returned from each one
        var processedData = {
            a: results[0],
            b: results[1],
            c: results[2]
        };
        res.send(processedDAta)
    })

})

您也可以自己这样做(并且是学习如何组织node.js代码的好习惯)。callbackhell是使用命名函数和模块来组织回调的很好的写法。

这是一种可行的方法。 (未经测试)

app.get('/endpoint',function(req, res){
    var dataSources = ['url1', 'url2',url3];
    var requestData = [];

    processRequestData = function(){
    //do you stuff here
    res.send(processedData);
    };
    dataSources.forEach(function(dataSource){
        request.get(dataSource,function(err,result){
            //handle error

            requestData.push(result);
            if(requestData.length == dataSources.length){
                processRequestData();
            }
        })
    })
});

答案 1 :(得分:2)

Async.js(https://github.com/caolan/async)可以帮助完成这样的任务。一个简单的例子:

app.get('/resource', function(req, res){
    // object to send back in the response
    var results = {};

    // helper function to make requests and handle the data to results object
    var getData = function(url, propertyName, next){
      http.get(url, function(err, data){
        // let async.js know if there is an error
        if(err) return next(err);
        // save data to results object
        results[propertyName] = data;
        // async.js needs us to notify it when each operation is complete - so we call the callback without passing any data back to
        next();
      });
    };

    // array of operations to execute in series or parallel
    var operations = [];

    operations.push(function(next){
        getData('http://url-one', 'users', next);
    });

    operations.push(function(next){
    getData('http://url-two', 'posts', next);
    });

    // async.js has a few options on how to execute your operations - here we use series
    async.series(operations, function(err){
        if(err){
            throw err;
        }
        // if we get to this point, all of the operations have exectued and called 
        // next() without any errors - send the response with a populated results object.
        res.send(results);
    });

});

我还没有尝试过这段代码,但它应该会让你对如何做到这一点有所了解。