J'utilise le async.eachLimit
fonction pour contrôler le nombre maximal d'opérations à la fois.
const { eachLimit } = require("async");
function myFunction() {
return new Promise(async (resolve, reject) => {
eachLimit((await getAsyncArray), 500, (item, callback) => {
// do other things that use native promises.
}, (error) => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
Comme vous pouvez le constater, je ne peux pas déclarer la fonction myFunction
comme asynchrone, car je n’ai pas accès à la valeur contenue dans le deuxième rappel de la fonction eachLimit
.
Vous utilisez efficacement les promesses dans la fonction exécuteur du constructeur de promesse, donc voici le anti-motif du constructeur de promesse .
Votre code est un bon exemple du risque principal: ne pas propager toutes les erreurs en toute sécurité. Lisez pourquoi là .
De plus, l'utilisation de async
/await
peut rendre les mêmes pièges encore plus surprenants. Comparer:
let p = new Promise(resolve => {
""(); // TypeError
resolve();
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e)); // Catches it.
avec un naïf (faux) async
équivalent:
let p = new Promise(async resolve => {
""(); // TypeError
resolve();
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e)); // Doesn't catch it!
Recherchez la dernière dans la console Web de votre navigateur.
La première fonctionne parce que toute exception immédiate dans une fonction exécuteur du constructeur Promise rejette commodément la nouvelle promesse construite (mais à l'intérieur de toute .then
tu es tout seul).
La seconde ne fonctionne pas car toute exception immédiate dans une fonction async
rejette la promesse implicite renvoyée par la fonction async
elle-même.
Comme la valeur de retour d'une fonction exécuteur de constructeur de promesse n'est pas utilisée, c'est une mauvaise nouvelle!
Il n'y a aucune raison pour que vous ne puissiez pas définir myFunction
comme async
:
async function myFunction() {
let array = await getAsyncArray();
return new Promise((resolve, reject) => {
eachLimit(array, 500, (item, callback) => {
// do other things that use native promises.
}, error => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
Pourquoi utiliser des bibliothèques de contrôle de concurrence obsolètes alors que vous avez await
?