节点中的JS Api请求循环
我想我最害怕避免与我的节点JS的回调地狱。但我试图做大量的API请求,并将其插入到我的数据库中。节点中的JS Api请求循环
我的问题在这里(当然)是我的for-loop在我完成我的请求和数据库插入之前运行并递增。
for(var i = 0; i <= 1 ; i++){
apiRequest = data[i];
apicall(apiRequest);
}
function apicall(urlApi){
request((urlApi), function(error, response, body){
if(error){
console.log("error");
} else if(!error && response.statusCode == 200){
var myobj = JSON.parse(body);
dbInsert(myobj);
}
});
}
function dbInsert(obj) {
//insert into database
}
如果其他人会来这个问题,我可以真实地建议我这篇文章,我通过joshvermaire读取响应后发现:
我建议使用类似async.each 。然后,你可以这样做:
async.each(data, function(apiRequest, cb) {
apicall(apiRequest, cb);
}, function(err) {
// do something after all api requests have been made
});
function apicall(urlApi, cb){
request((urlApi), function(error, response, body){
if(error){
console.log("error");
cb(error);
} else if(!error && response.statusCode == 200){
var myobj = JSON.parse(body);
dbInsert(myobj, cb);
}
});
}
function dbInsert(obj, cb) {
doDBInsert(obj, cb);
}
当dbInsert
方法完成,确保cb
回调被调用。如果您需要一系列操作,请参阅async.eachSeries
。
这将如何解决用户的问题?用户的问题究竟是什么? –
有几种方法可以解决这类问题。首先,如果您可以并行运行所有API调用(同时全部都在运行),并且它们在数据库中插入的顺序无关紧要,那么您可以通过这样做获得更快的结果(vs 。按顺序将它们序列化)。
在下面的所有选项,你可以使用此代码:
const rp = require('request-promise');
function apicall(urlApi){
return rp({url: urlApi, json: true}).then(function(obj){
return dbInsert(obj);
});
}
function dbInsert(obj) {
//insert into database
// return a promise that resolves when the database insertion is done
}
并行使用ES6标准少辉
let promises = [];
for (let i = 0; i <= data.length; i++) {
promises.push(apicall(data[i]));
}
Promise.all(promises).then(() => {
// all done here
}).catch(err => {
// error here
});
使用蓝鸟无极图书馆
随着并行蓝鸟诺言库,你可以使用Promise.map()
迭代你的数组,你可以传递concurrency
选项来控制同时有多少个异步调用正在运行,这可能会使数据库或目标API主机不堪重负,并可能有助于控制最大内存使用量。
Promise.map(data, apiCall, {concurrency: 10}).then(() => {
// all done here
}).catch(err => {
// error here
});
在系列采用标准ES6少辉
如果你有连载他们出于某种原因,如为了插入数据库,那么你就可以是这样做的。下面显示的.reduce()
模式是使用标准ES6阵列上连载的承诺操作的经典方式:
data.reduce(data, (p, item) => {
return p.then(() => {
return apicall(item);
});
}, Promise.resolve()).then(() => {
// all done here
}).catch(err => {
// error here
});
使用串联的蓝鸟公司承诺
蓝鸟有Promise.mapSeries()
迭代访问串联数组,调用一个函数在数组中的每个项目上返回一个promise,这比手动操作要简单一点。
Promise.mapSeries(data, apiCall).then(() => {
// all done here
}).catch(err => {
// error here
});
查看async/await - 它们将允许您在apicall处于活动状态时暂停。 – theGleep
'我'递增不应该在你的情况下造成问题。你的问题可能是别的。 –