Ola*_*son 1 loops callback request node.js
我正在尽我最大的努力避免我的 Node JS 回调地狱。但是我正在尝试发出大量 api 请求并将它们插入到我的数据库中。
我的问题(当然)是我的 for 循环在完成请求和数据库插入之前运行并增加 i 。
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
}
Run Code Online (Sandbox Code Playgroud)
如果其他人会问这个问题,我可以真正推荐这篇博文,这是我在阅读joshvermaire的回复后发现的:
有多种方法可以解决此类问题。首先,如果您可以并行运行所有 API 调用(同时所有 API 调用)并且它们插入数据库中的顺序无关紧要,那么您可以通过这样做更快地获得结果(与.按顺序序列化它们)。
在以下所有选项中,您将使用以下代码:
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
}
Run Code Online (Sandbox Code Playgroud)
并行使用 ES6 标准 Promises
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
});
Run Code Online (Sandbox Code Playgroud)
并行使用 Bluebird Promise 库
使用 Bluebird Promise 库,您可以使用它Promise.map()来迭代您的数组,并且您可以将concurrency选项传递给它来控制同时进行的异步调用的数量,这可能不会使数据库或目标 API 主机不堪重负,并且可能有助于控制最大内存使用量。
Promise.map(data, apiCall, {concurrency: 10}).then(() => {
// all done here
}).catch(err => {
// error here
});
Run Code Online (Sandbox Code Playgroud)
使用标准 ES6 Promise 串联
如果您出于某种原因必须序列化它们,例如按顺序插入数据库,那么您可以这样做。下面.reduce()显示的模式是使用标准 ES6 在数组上序列化 promise 操作的经典方法:
data.reduce(data, (p, item) => {
return p.then(() => {
return apicall(item);
});
}, Promise.resolve()).then(() => {
// all done here
}).catch(err => {
// error here
});
Run Code Online (Sandbox Code Playgroud)
串联使用 Bluebird Promise
Bluebird 有一个连续Promise.mapSeries()迭代数组,调用一个函数,该函数返回对数组中每个项目的承诺,这比手动执行要简单一些。
Promise.mapSeries(data, apiCall).then(() => {
// all done here
}).catch(err => {
// error here
});
Run Code Online (Sandbox Code Playgroud)