我有一项任务,我必须进行700次REST API调用。我使用了循环,但循环的运行时间超过了AWS Lambda服务的超时。有什么方法可以同时进行调用并合并结果。我正在使用节点JS,但也欢迎使用python中的解决方案
以下是我正在运行的代码示例:
HitBTCData = {}
for item in exchanges:
itemlist = item.split('-')
response = requests.get('https://min-
api.cryptocompare.com/data/histominute?
fsym='+itemlist[0]+'&tsym='+itemlist[1]+'&limit=2000&aggregate=1
&e=HitBTC').json()
if itemlist[0]+itemlist[1] not in HitBTCData:
HitBTCData[itemlist[0]+itemlist[1]] = []
HitBTCData[itemlist[0]+itemlist[1]].append(response['Data'])
while response['Type'] != 1:
time = response['TimeFrom']
response = requests.get('https://min-
api.cryptocompare.com/data/histominute?
fsym='+itemlist[0]+'&tsym='+itemlist[1]+
'&limit=2000&aggregate=1&toTs='+str(time)+'&e=HitBTC').json()
if response['Type'] != 1:
HitBTCData[itemlist[0]+itemlist[1]]
.append(response['Data'])
HitBTCData[itemlist[0]+itemlist[1]] =
HitBTCData[itemlist[0]+itemlist[1]][::-1]
答案 0 :(得分:0)
在Node.js中使用循环并且调用将同时运行,但为了确保在退出lambda之前处理所有调用,您需要使用某种形式的计数器来确保所有查询都已结束。
示例:
var request = require('request');
var results = [];
var runningQueries = 0;
exchanges.forEach(function (item) {
++runningQueries;
callAPI (item, function (err, data) {
if (err) {
results.push(err)
--runningQueries;
} else {
results.push(data)
--runningQueries;
}
if (runningQueries == 0) {
// all call results have been collated, so do something
}
})
})
您需要构建自己的callAPI函数。另外,我对这里推送到阵列的内容有点懒,但它只是给你一个框架。
答案 1 :(得分:0)
您可以使用Promise.all()
轻松地做到这一点:
const urls = [...];
const requestFunction = async (url) => {
// all your ifs go here
let data = await request(url);
// transform/sanitize your data
return data;
}
const allResults = await Promise.all(urls.map(requestFunction));
// you now have an array of results
Promise.all()
的唯一缺点是,如果任何承诺被拒绝,一切都会失败。因此,我建议捕获错误并使用null
或类似的方法来解决。
您可以执行for
循环以生成URL数组new Array(700).map(...)
,或者由于看起来您已经具有某种数组,只需.map()
即可直接执行更多操作在请求函数内部进行转换。