如何解决尝试使用async.parallelLimit进行连续的并行API调用
我有一个对象数据数组,例如[{number:1},{number:2},{number:3} ... {number:100}]。并希望连续10个批次进行并行API调用,直到处理完整个数组为止。
我该怎么办?
这是我的代码。它超过了前10个,但随后停止了。
const async = require("async");
const axios = require("axios");
const calls = require("../model/data"); // [{number:1},{number:2},{number:3},...{number:100}]
let makeAPICall = function (request,callback) {
axios
.post("http://www.api.com/",{
number: `${request.number}`,webhookURL: "http://localhost:8000/",})
.then(function (response) {})
.catch(function (err) {
callback(err);
});
};
const functionArray = calls.map((request) => {
return (callback) => makeAPICall(request,callback);
});
exports.startCalls = (req,res,next) => {
async.parallelLimit(functionArray,10,(err,results) => {
if (err) {
console.error("Error: ",err);
} else {
console.log("Results: ",results.length,results);
}
});
};
解决方法
因此,您的方法有些落后,因为您已经返回了promise(Axios),这是管理异步操作的现代方法,现在您正尝试将其转换回普通回调,以便可以使用老式库(异步库)。运行10也会比较慢,通常不需要全部等待10结束,然后再开始运行。
相反,我建议您使用已经拥有的Axios承诺。您可以使用设置为using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
public static void Run(TimerInfo myTimer,TraceWriter log)
{
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
string accountSid = "ACc61b294f03cf077ccb3bc7fe4a1550fb";
string authToken = "98417c610cb6e8c88217f1530b17f1e7";
var client = new TwilioClient(accountSid,authToken);
client.SendMessage(
"+12184893932",// Insert your Twilio from SMS number here
"+15138841613",// Insert your verified (trial) to SMS number here
"hello from Azure Functions!" + DateTime.Now
);
}
的Bluebird的.map()
,也可以使用以下代码为您提供并行运行承诺产生函数的功能,同时控制飞行中的最大数量在任何给定时间:
concurrency
然后您将像这样使用它:
// takes an array of items and a function that returns a promise
function mapConcurrent(items,maxConcurrent,fn) {
let index = 0;
let inFlightCntr = 0;
let doneCntr = 0;
let results = new Array(items.length);
let stop = false;
return new Promise(function(resolve,reject) {
function runNext() {
let i = index;
++inFlightCntr;
fn(items[index],index++).then(function(val) {
++doneCntr;
--inFlightCntr;
results[i] = val;
run();
},function(err) {
// set flag so we don't launch any more requests
stop = true;
reject(err);
});
}
function run() {
// launch as many as we're allowed to
while (!stop && inflightCntr < maxConcurrent && index < items.length) {
runNext();
}
// if all are done,then resolve parent promise with results
if (doneCntr === items.length) {
resolve(results);
}
}
run();
});
}
在此处查看另一个类似的问题:Promise.all consumes all my RAM
,如果您真的想以固定的批次运行它们,然后在运行更多请求之前整个批次完成,则可以执行以下操作:
const axios = require("axios");
const calls = require("../model/data"); // [{number:1},{number:2},{number:3},...{number:100}]
function makeAPICall(request) {
return axios.post("http://www.api.com/",{
number: `${request.number}`,webhookURL: "http://localhost:8000/",});
};
async function runBatches(array,batchSize,fn) {
let index = 0;
let results = [];
while (index < array.length) {
let promises = [];
for (let num = 0; num < batchSize && index < array.length; ++num) {
promises.push(makeAPICall(array[index++]));
}
let batchResults = await Promise.all(promises);
results.push(...batchResults);
}
return results;
}
runBatches(calls,10,makeAPICall).then(results => {
// all results in order here
console.log(results);
}).catch(err => {
console.log(err);
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。