因此,我对此有过分担心,这是一个之前多次问过的问题,但是我进行了搜索,每个问题似乎都针对不同的具体情况而量身定制。如果您看到它是重复的,请标记它并指向正确的方向。
一般的最小示例:
我有一个数组data
,想对data
中的每个元素进行API调用,向每个元素中添加内容。 然后我想找回处理过的数据。
我的第一次尝试(使用伪代码:ish):
// function that recursively makes the calls
makeCalls(data,i,resolve){
// base case, we're done
if(i === data.length){
return resolve(data);
}
const options = {
url: "http://theapi.com/?name="+data[i].name
};
request.post(options,function(error,response,body){
data[i].item = body.item;
i++;
return makeCalls(data,i,resolve);
}
}
// later on in my code I call the function
new Promise(resolve => makeCalls(data,0,resolve))
.then(returnedData => console.log("done!"))
现在,该解决方案起作用了(尽管680个调用花费了264s的时间),但是由于调用互不依赖,所以我认为我可以加快速度,所以我做了一个循环而不是递归:
// function that iteratively makes the calls
makeCalls(data,resolve){
let j = 0
const options = {
url: "http://theapi.com/?name="+data[i].name
};
for(let i = 0; i < data.length; i++){
request.post(options,function(error,response,body){
data[i].item = body.item;
j++;
if(j === data.length)
return resolve(data);
}
}
}
现在680个电话仅需56秒。也许这是完全正常的,但是由于我一直在编写代码,所以我真的很想知道是否在节点中有“惯用的”方法吗?我是说我真的应该像这样Promise
并将resolve-object传递给函数吗?有没有一种“适当的”方式可以立即进行大量的API调用?
如果有人感到好奇,data
是Spotify-API的一系列曲目,不幸的是,它们仅提供艺术家级别的流派。我需要曲目级别的流派,因此请转到LastFM-API,该API的端点为我提供了曲目的顶部标签。唯一的问题是,我需要针对每个音轨进行此调用:(
答案 0 :(得分:1)
我会在request
上使用包装器来返回承诺。参见list
考虑到这一点,我将使用map函数来简化每个请求并更新所有项目,并通过Promise.all()等待您的所有诺言
使用request-promise作为示例
const options = {
url: "http://theapi.com/?name=" // asumimng you're using an object because there are other options
};
let promises = data
.map(element => rp({ ...options, url: options.url + element.name })
.then(response => element.item = response.item)
);
return Promise.all(promises).then(() => console.log('done!'));
无论如何,您在此处修复的大部分内容是使代码更简洁,更声明性。 可能花费您的时间是因为所有这些请求本身都很慢。您使用的API是否为您提供了在一个请求或类似请求中发送多个ID的机会?您可能想在一个请求中做到这一点