一起制作700个API调用并使用AWS Lambda合并数据

时间:2018-06-01 22:36:23

标签: python node.js rest api aws-lambda

我有一项任务,我必须进行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]

2 个答案:

答案 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()即可直接执行更多操作在请求函数内部进行转换。