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

Posted

技术标签:

【中文标题】从 node.js/express.js 中的多个异步源构建对象【英文标题】:Building an object from multiple asynchronous sources in node.js/express.js 【发布时间】:2014-10-10 05:30:37 【问题描述】:

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

所以我向使用 node/express js 的 javascript 专业人士提出问题。如何将多个 JSON 对象源同步到一个对象中,以便在一个响应中返回到客户端?有没有你使用的库或一些回调魔法?

提前感谢您的任何帮助!

【问题讨论】:

【参考方案1】:

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);
    );

);

我还没有真正尝试过这段代码,但它应该可以让你很好地了解如何去做。

【讨论】:

你可以像这样简化你的代码:gist,你可以在async.seriesasync.parallelasync.auto之间进行选择 我有点希望在一条路线上使用它,特别是因为我使用一些节点模块来获取多个来源,但你说如果我不想完美地处理一堆将我必须为异步调用的每个 JSON 对象构建单独的路由的回调串在一起? P.S 感谢您的想法和快速响应,非常感谢! 不,他不是这么说的。在他的示例中,这些不是路线。这是获取数据的http函数调用。所以将遍历类上定义的属性,当它们都完成后,您将在最终回调中处理结果。这是此操作的文档:github.com/caolan/async#seriestasks-callback【参考方案2】:

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();
            
        )
    )
);

【讨论】:

我明白你在说什么,非常感谢你的例子和澄清! processDataRequest 不存在,request.data.push 应该是 requestData.push,请注意。

以上是关于从 node.js/express.js 中的多个异步源构建对象的主要内容,如果未能解决你的问题,请参考以下文章

无法访问我的站点中的链接(复制和粘贴):Node.js - Express.js - Webpack - Vue.js - 历史模式

在 Node.js/Express.js 中,如何将 JSON 对象从服务器传输到客户端?

将方法添加到node.js express.js coffeescript中的字符串类

node.js + express.js + socket.io 授权:没有cookie

每次在 Node.js (Express.js) 中发出 API 请求之前,如何简化 Fetching Auth token?

Node.js + Express.js |尝试设置 HTTPS 服务器