Il existe plusieurs façons d'aborder ce type de problème. Premièrement, si vous pouvez exécuter tous les appels d'API en parallèle (tout en vol en même temps) et peu importe l'ordre dans lequel ils sont insérés dans votre base de données, vous pouvez obtenir un résultat beaucoup plus rapidement (vs en les sérialisant dans l'ordre).
Dans toutes les options ci-dessous, vous pouvez utiliser ce code:
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
}
parallèle à l'aide ES6 standard promesses
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
});
parallèle à l'aide Bluebird Promise Library
Avec la Bibliothèque Bluebird Promise, vous pouvez utiliser Promise.map()
pour itérer votre tableau et vous pouvez lui passer l'option concurrency
pour contrôler combien d'appels asynchrones sont en cours en même temps, ce qui pourrait éviter de surcharger la base de données ou l'hôte API cible et pourrait aider à contrôler l'utilisation maximale de la mémoire.
Promise.map(data, apiCall, {concurrency: 10}).then(() => {
// all done here
}).catch(err => {
// error here
});
Dans la série en utilisant la norme ES6 promesses
Si vous devez sérialisation pour une raison quelconque, comme l'insertion dans la base de données afin, alors vous pouvez le faire comme ça. Le schéma .reduce()
illustré ci-dessous est un moyen classique pour sérialiser opérations de promesse sur un tableau en utilisant ES6 standard:
data.reduce(data, (p, item) => {
return p.then(() => {
return apicall(item);
});
}, Promise.resolve()).then(() => {
// all done here
}).catch(err => {
// error here
});
Dans la série utilisant Bluebird promesses
Bluebird a une Promise.mapSeries()
qui itère un tableau en série, appelant une fonction qui renvoie une promesse sur chaque élément du tableau, ce qui est un peu plus simple que de le faire manuellement.
Promise.mapSeries(data, apiCall).then(() => {
// all done here
}).catch(err => {
// error here
});
Regardez dans async/await - ils vous permettront de faire une pause pendant que apicall est actif. – theGleep
'i' incrémenter ne devrait pas causer de problème dans votre cas. Votre problème est probablement autre chose. –