【问题标题】:How to make a series of parallel API requests with dynamic parameters in nodejs如何在nodejs中使用动态参数进行一系列并行API请求
【发布时间】:2015-07-29 15:08:38
【问题描述】:

我想进行一系列 API 调用,根据存储在数组中的参数值(大约 30-40 个值)更改 URL 中的单个参数值。我正在使用 NodeJS 和 Express。以下是我为此写的一个 sn-p:

var express = require('express');
var router = express.Router();
var rest = require('restler');

router.get('/myroute', function(req, res, next){
    parameterArray = [ /* A list of parameter values in here gathered from two more API calls */];
    returnArray = [];

    for(var i = 0; i < parameterArray.length; i++){
        var url = 'https://api.example.org?parameter=' + parameterArray[i];
        rest.get(url).on('success', function(data){
          // after some processing on data
          returnArray.push(processedData);
        });
    }

    res.json(returnArray);
});

module.exports = router;

我有两个问题:

1.) 目前router.get('/myroute') 大约需要 40-50 秒才能完成并返回。我怎样才能让它们更快?我看过node-webworker-threads。有没有更好的选择?

2.) 在上面的代码中,路由函数router.get('/myroute') 返回空的returnArray,因为restler 进行了异步调用。如何确保函数仅在收到所有 API 请求(并将处理后的数据推送到 returnArray)后才返回。

【问题讨论】:

    标签: javascript node.js multithreading rest express


    【解决方案1】:

    1) 这在很大程度上取决于您的 ajax 调用的响应(另一端的网络流量和服务器处理),因此不确定您是否真的可以通过多线程加快速度。

    2) rest.get() 是一个异步调用。使用常规 for 循环将不起作用,因为它不会等待所有 ajax 调用完成。这就是 returnArray 为空的原因。您可以使用 async.each() (并行处理),但我建议您使用 async.eachLimit() 以便您可以限制 ajax 调用的数量。如果您的服务器无法同时处理那么多事务,那么将其中的 30-40 个刷新到您的服务器可能不是一个好主意。这是修改后的代码(请注意,我一次将 ajax 调用限制为 5 个,您可以使用这个数字来看看什么最适合您):

    var express = require('express');
    var router = express.Router();
    var rest = require('restler');
    var async = require('async');
    
    router.get('/myroute', function(req, res, next){
        var parameterArray = [ /* A list of parameter values in here gathered from two more API calls */];
        var returnArray = [];
    
        async.eachLimit(parameterArray, 5, function(param, eachCb) {
            var url = 'https://api.example.org?parameter=' + param;
            rest.get(url).on('complete', function(data){
                var processedData;
                // after some processing on data
                returnArray.push(processedData);
                eachCb(null);
            });
        }, function(err) {
            // done with all ajax calls
            res.json(returnArray);
        });
    });
    
    module.exports = router;
    

    【讨论】:

    • 非常感谢。这很有帮助。我的意思是 API 调用大约需要 40 秒才能返回实际上是 router.get('/myroute') 整体所花费的时间。我已经编辑了这个问题。另外,你能告诉我每个Cb是什么吗?再次感谢。
    • async.each() 的回调。与其将它命名为“回调”,不如说 eachCb 有点意思,通过查看代码,我马上就知道这个回调来自哪里。否则,当您有嵌套异步调用时,所有嵌套异步调用的回调的“回调”会有点混乱。
    猜你喜欢
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 1970-01-01
    • 2021-04-06
    • 2020-12-31
    • 2013-07-11
    相关资源
    最近更新 更多