web-dev-qa-db-fra.com

Est-ce un anti-modèle d'utiliser async / wait à l'intérieur d'un nouveau constructeur Promise ()?

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.

46
user5487299

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 .

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!

Votre code

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?

36
jib