循环内的多个API调用 我在循环中进行多个API调用,函数在promise内部调用并将数据传递给body,这部分工作正常,在函数中返回一个对API进行多次调用的promise,然后继续进行我必须得到所有的结果。但当我控制台记录结果时,它显示空数组。
var rp = require('request-promise');
var watchonlinemovie = [];
exports.db = function(body){
return new Promise((resolve,reject)=>{
if(body.lenght > 0)
{
body.forEach(movie)
{
let title = movie.title;
title = (title.slice(0,title.indexOf('('))).trim();
let year = movie.title;
year = year.slice(year.indexOf('(')+1,year.indexOf(')'));
let call = "http://www.omdbapi.com/?t="+title+"&y="+year+"&apikey="+key2+"&plot=full";
rp(call)
.then((body) => {
let movie = JSON.parse(body);
watchonlinemovie.push({
title: movie.Title,
year:movie.Year,
rating:movie.Rated,
duration:movie.Runtime,
genre:movie.Genre,
director:movie.Director,
actors:movie.Actors,
image:movie.Poster,
href:movie.link,
});
})
.catch(err => {
reject(err);
});
}
}
resolve(watchonlinemovie);
});
}
答案 0 :(得分:0)
您可以使用async.eachOfLimit继续所有行。您可以将限制调整为1比1或5比5,或全部并行(如果您有数千行,请不要这样做。)
10乘10的例子。
var async = require("async");
var rp = require('request-promise');
exports.db = function(body){
return new Promise((resolve,reject)=>{
var watchonlinemovie = [];
// change the limit here
// process all request with a batch of 10
async.eachOfLimit(body, 10, function(movie, i, ecb){
// function called for each line in body
let title = movie.title;
title = (title.slice(0,title.indexOf('('))).trim();
let year = movie.title;
year = year.slice(year.indexOf('(')+1,year.indexOf(')'));
let call = "http://www.omdbapi.com/?t="+title+"&y="+year+"&apikey="+key2+"&plot=full";
rp(call)
.then((body) => {
let movie = JSON.parse(body);
watchonlinemovie.push({
title: movie.Title,
year:movie.Year,
rating:movie.Rated,
duration:movie.Runtime,
genre:movie.Genre,
director:movie.Director,
actors:movie.Actors,
image:movie.Poster,
href:movie.link,
});
// proceed next movie
return ecb(null);
})
.catch(err => {
// stop the async process
return ecb(err);
});
})
}, function(err){
// final callback, when all request in the body has been proceed
if(err)
{
reject(err);
}
else
{
resolve(watchonlinemovie);
}
});
});
}
答案 1 :(得分:0)
这是一个使用promises的解决方案,我添加了一些不允许承诺拒绝的内容,而是创建了Fail
类型值,您可以从结果中选择它们。
如果您需要限制,可以从here导入文件。
var rp = require('request-promise');
const movieToUrl = key2 => movie => {
const title = movie.title.slice(0, title.indexOf('(')).trim();
const year = movie.title.slice(title.indexOf('(') + 1, title.indexOf(')'));
let call = "http://www.omdbapi.com/?t=" + title + "&y=" + year +
"&apikey=" + key2 + "&plot=full";
};
const movieDataToMovieInstance = movie => ({
title: movie.Title,
year: movie.Year,
rating: movie.Rated,
duration: movie.Runtime,
genre: movie.Genre,
director: movie.Director,
actors: movie.Actors,
image: movie.Poster,
href: movie.link,
});
const Fail = function(reason){this.reason=reason;};
const isFail = x=>(x&&x.constructor)===Fail;
const isNotFail = x=>!isFail(x);
//if you want to throttle promises like max5 active or max5 per second
// you can use throttle library here:
// https://github.com/amsterdamharu/lib/blob/master/src/index.js
//const max5=lib.throttle(5);//this is max 5 active connections
//const max5=throttlePeriod(5,1000);//this is max 5 per second
exports.db = function (body) {
return Promise.all(
body.map(
movieToUrl(key2)//key2 comes out of nowhere
//throttled version
//.then(max5(rp))
.then(rp)
.then(movieDataToMovieInstance)
.catch(err=>new Fail([body,err]))
)
);
};
//example how to use:
exports.db(someBody)
.then(
results=>{
const successes = results.filter(isNotFail);
const failures = results.filter(isFail);
}
)