Javascript 如何优化async.js API调用?

Javascript 如何优化async.js API调用?,javascript,node.js,async.js,Javascript,Node.js,Async.js,我正在使用async.concat进行API调用。我使用此函数而不是其他async.js函数,因为: A.在所有调用完成后,我需要在1个数组中显示结果 B.async.concat并行执行调用,性能对于该程序非常重要 问题是:似乎没有一种简单的方法来限制并发连接。该程序可能需要进行大约100-300次不同的API调用(在第一次API调用之前,我无法确切知道),并且我不想猛击服务器 我考虑过: 将concat()嵌套在async.doWhilst()中,并每次执行5-10个块。但这感觉有点太偷工减

我正在使用async.concat进行API调用。我使用此函数而不是其他async.js函数,因为:

A.在所有调用完成后,我需要在1个数组中显示结果

B.async.concat并行执行调用,性能对于该程序非常重要

问题是:似乎没有一种简单的方法来限制并发连接。该程序可能需要进行大约100-300次不同的API调用(在第一次API调用之前,我无法确切知道),并且我不想猛击服务器

我考虑过:

  • 将concat()嵌套在async.doWhilst()中,并每次执行5-10个块。但这感觉有点太偷工减料了,我相信以前有人解决过这个问题

  • 我还可以使用一个异步函数w/a Limit选项,并简单地将每个结果推送到函数作用域上方的数组中。我是否应该担心多个API调用试图同时推送到同一阵列?还是单线程意味着这不是问题


  • 这里还有其他简单高效的途径吗?只要它速度快,而且我只剩下一个包含所有对象的数组,我就不关心这里的大多数其他因素。

    对于您所需要的,node'js似乎是一个很好的工具。如果您正在谈论大约100-300个API请求,那么从
    节点
    发出请求不会有问题,因此关闭请求服务器(在本例中为
    节点
    )不是问题

    但是,如果您对必须处理这些调用的同一台服务器执行这些API调用,则可能会出现问题,因此在这种情况下,如果请求数达到最佳值,则应限制批调用数

    使用promise库:

    // mock data
    // supposing that this is the array of apis to call
    var requestsToComplete = [c1, c2, c3, ..., c300];
    
    var Promise = require('bluebird');
    var results = [];
    
    var fakeCounter = 0;
    // fake api call... for demonstration purposes
    function processApiCall(apiData) {
        // simulate api call...
        var promise = new Promise(function(resolve, reject) {
            setTimeout(function() { resolve(fakeCounter++) });
        });
        return promise;
    }
    
    function processBatch(reqs, batchSize, skip) {
        var batchRequests = [];
        for (var i = skip; i < Math.min(i+batchSize, reqs.length); i++) {
            var requestPromise = processApiCall(reqs[i]);
            batchRequests.push(requestPromise);
        }
        // process all 
        return Promise.all(batchRequests);
    }
    
    function makeApiCalls() {
        var batchCount = 0;
        var batchSize = 10;
        var promise = Promise.resolve();
        while (batchCount < requestsToComplete.length) {
            batchCount += batchSize;
            promise = promise.then(function() {
                 return processBatch(requestsToComplete, batchSize, batchCount);
            }).then(function(batchResponse) {
                 results = results.concat(batchResponse);
            });
        }
    
        promise.then(function() {
            // all api calls finished
            // results now contain all the responses in order of calling, i.e.
            results = [c1Response, c2Response, ..., c300Response];
    
            // well, in our case results will be an array of fake results...
            results = [0, 1, 2, ..., 300];
        });
    }
    

    对于您所需要的,
    node'js
    似乎是一个很好的工具。如果您正在谈论大约100-300个API请求,那么从
    节点
    发出请求不会有问题,因此关闭请求服务器(在本例中为
    节点
    )不是问题

    但是,如果您对必须处理这些调用的同一台服务器执行这些API调用,则可能会出现问题,因此在这种情况下,如果请求数达到最佳值,则应限制批调用数

    使用promise库:

    // mock data
    // supposing that this is the array of apis to call
    var requestsToComplete = [c1, c2, c3, ..., c300];
    
    var Promise = require('bluebird');
    var results = [];
    
    var fakeCounter = 0;
    // fake api call... for demonstration purposes
    function processApiCall(apiData) {
        // simulate api call...
        var promise = new Promise(function(resolve, reject) {
            setTimeout(function() { resolve(fakeCounter++) });
        });
        return promise;
    }
    
    function processBatch(reqs, batchSize, skip) {
        var batchRequests = [];
        for (var i = skip; i < Math.min(i+batchSize, reqs.length); i++) {
            var requestPromise = processApiCall(reqs[i]);
            batchRequests.push(requestPromise);
        }
        // process all 
        return Promise.all(batchRequests);
    }
    
    function makeApiCalls() {
        var batchCount = 0;
        var batchSize = 10;
        var promise = Promise.resolve();
        while (batchCount < requestsToComplete.length) {
            batchCount += batchSize;
            promise = promise.then(function() {
                 return processBatch(requestsToComplete, batchSize, batchCount);
            }).then(function(batchResponse) {
                 results = results.concat(batchResponse);
            });
        }
    
        promise.then(function() {
            // all api calls finished
            // results now contain all the responses in order of calling, i.e.
            results = [c1Response, c2Response, ..., c300Response];
    
            // well, in our case results will be an array of fake results...
            results = [0, 1, 2, ..., 300];
        });
    }
    

    ?它们是否通常更具性能?我原以为它们只是在语法上不同/更容易推理,node的单线程模型意味着没有两个API调用会同时将结果推送到数组。此外,所有API调用都将同时处理结果,但不是并行处理,您不应该担心
    竞争条件。至少在这里和这个级别上没有。@eAbi-谢谢,我知道节点是单线程的,但没有考虑到这对这个主题的影响——这解释了很多。所以,“并行”执行100个API调用可能用词不当——听起来更像是串行发出调用,并行等待响应,串行处理结果——这准确吗?如果是这样的话,听起来API调用实际上已经受到限制了。@Brandon是的,你说得对。:?他们通常表现得更出色吗?我原以为它们只是在语法上不同/更容易推理,node的单线程模型意味着没有两个API调用会同时将结果推送到数组。此外,所有API调用都将同时处理结果,但不是并行处理,您不应该担心
    竞争条件。至少在这里和这个级别上没有。@eAbi-谢谢,我知道节点是单线程的,但没有考虑到这对这个主题的影响——这解释了很多。所以,“并行”执行100个API调用可能用词不当——听起来更像是串行发出调用,并行等待响应,串行处理结果——这准确吗?如果是这样的话,听起来API调用实际上已经受到限制了。@Brandon是的,你说得对。:)