Maison  >  Article  >  interface Web  >  Pourquoi Promise.all se résout-il avec un tableau de valeurs non définies lors de l'utilisation de fonctions asynchrones dans une carte ?

Pourquoi Promise.all se résout-il avec un tableau de valeurs non définies lors de l'utilisation de fonctions asynchrones dans une carte ?

DDD
DDDoriginal
2024-11-02 09:27:02585parcourir

Why is Promise.all resolving with an array of undefined values when using async functions within a map?

Promise.all Résoudre un tableau d'indéfinis : dévoiler le mystère

Les promesses fournissent un modèle de programmation asynchrone, permettant une meilleure lisibilité du code et un meilleur contrôle du flux. Cependant, des problèmes inattendus surviennent parfois. Cette question explore pourquoi un Promise.all renvoie un tableau d'indéfinis et se résout prématurément.

Le code en question suit un modèle typique d'enchaînement de promesses :

<code class="javascript">const getQueries = (models, dbId, dateStart, dateEnd) => {
  return new Promise((resolve, reject) => {
    // Fetch database and perform operations
    .then(extractQueries, reject)
      .then(sortQueries, reject)
      .then(onlyTen, reject)
      .then(addText, reject)
      .then((queries) => {
        console.log("getQueries finished", queries);
        resolve(queries);
      }, reject);
  });
};</code>

Après avoir terminé avec succès la première opérations, le problème survient au sein de la fonction addText :

<code class="javascript">const addText = (queries) => {
  return Promise.all(queries.map((query) => {
    // Oops! We're missing a `return` here!
    models.queries.findById(query.queryId, {
      raw: true,
      attributes: ["query"],
    })
      .then((queryFetched) => {
        query.text = queryFetched.query;
        console.log(query);

        return Promise.resolve(query);
      }, (error) => {
        return Promise.reject(error);
      });
  }));
};</code>

La cause première du problème réside dans l'instruction return manquante dans la fonction de rappel de carte. Promise.all attend un tableau d'objets Promise, mais sans le retour, le rappel renvoie undéfini pour chaque élément du tableau des requêtes.

En conséquence, Promise.all se résout immédiatement avec un tableau d'objets non définis, avant même les promesses réelles à l’intérieur de la carte ont une chance de se résoudre. Cette résolution prématurée entraîne un comportement inattendu et un tableau de valeurs non définies.

Pour résoudre le problème, il est crucial d'ajouter l'instruction return avant chaque invocation de Promise dans la fonction addText :

<code class="javascript">const addText = (queries) => {
  return Promise.all(queries.map((query) => {
    return models.queries.findById(query.queryId, {
      raw: true,
      attributes: ["query"],
    })
      .then((queryFetched) => {
        query.text = queryFetched.query;
        console.log(query);

        return Promise.resolve(query);
      }, (error) => {
        return Promise.reject(error);
      });
  }));
};</code>

Maintenant, Promise.all attendra correctement que toutes les promesses du tableau soient résolues, ce qui donnera la sortie attendue contenant les résultats de la requête.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn