web-dev-qa-db-fra.com

Utiliser les promesses de mangouste avec async / wait

J'essaie de comprendre comment utiliser les promesses Mongoose avec la fonctionnalité async/wait de Node.js. Lorsque ma fonction printEmployees est appelée, je souhaite enregistrer la liste des employés interrogés par la fonction orderEmployees. Tandis que le console.log déclaration à l'intérieur de orderEmployees renvoie la requête attendue, le console.log à l'intérieur de printEmployees renvoie undefined, suggérant que je ne retourne pas la promesse correctement.

Je suis nouveau sur des promesses si possible que je ne comprends pas correctement le paradigme ... toute aide est très appréciée.

  printEmployees: async(company) => {
    var employees = await self.orderEmployees(company);
    // SECOND CONSOLE.LOG
    console.log(employees);
  },

  orderEmployees: (companyID) => {
    User.find({company:companyID})
    .exec()
    .then((employees) => {
      // FIRST CONSOLE.LOG
      console.log(employees);
      return employees;
    })
    .catch((err) => {
      return 'error occured';
    });
  },
19
Patrick Connors

Vous devez return votre Promise, sinon vous attendez une fonction qui retourne undefined.

orderEmployees: (companyID) => {
  return User.find({ company:companyID }).exec()
}

Actuellement, vous attendez une promesse alors le code de la prochaine ligne sera exécuté immédiatement; avant la promesse que vous voulez vraiment attendre, résolue réellement.

Aussi vraiment important, vous devriez throw au lieu de return dans votre .catch gestionnaire.

18
Nik Kyriakides

Pour que orderEmployees se comporte comme des fonctions asynchrones, vous devez retourner la promesse résultante. Il y a deux règles à suivre lors de l’utilisation de promesses sans async/await mots clés:

  1. Une fonction est asynchrone si elle retourne un Promise
  2. Si vous avez une promesse (par exemple, retournée par une fonction asynchrone), vous devez soit appeler .then dessus ou retournez-le.

Quand vous utilisez async/await alors vous devezawait sur les promesses que vous obtenez.

Ceci dit, vous remarquerez que vous ne retournez pas la promesse générée à l'intérieur de orderEmployees. Facile à corriger, mais il est également facile de réécrire cette fonction en async aussi.

orderEmployees: (companyID) => {
  return User.find({company:companyID}) // Notice the return here
  .exec()
  .then((employees) => {
    // FIRST CONSOLE.LOG
    console.log(employees);
    return employees;
  })
  .catch((err) => {
    return 'error occured';
  });
},

ou

orderEmployees: async(companyID) => {
  try {
    const employees = await User.find({company:companyID}).exec();
    console.log(employees);
    return employees;
  } catch (err) {
    return 'error occured';
  }
},

PS: le traitement des erreurs est quelque peu imparfait. Nous ne traitons généralement pas les erreurs en renvoyant une chaîne d'erreur à partir d'une fonction. Il est préférable que l'erreur se propage dans ce cas et la gère à partir d'un code d'interface utilisateur de niveau supérieur.

24
Tamas Hegedus

Vous ne retournez pas une promesse de orderEmployees.

printEmployees: async(company) => {
  var employees = await self.orderEmployees(company);
  // SECOND CONSOLE.LOG
  console.log(employees);
},

orderEmployees: (companyID) => {
  return User.find({company:companyID})
 .exec()
 .then((employees) => {
   // FIRST CONSOLE.LOG
   console.log(employees);
   return employees;
 })
 .catch((err) => {
   return 'error occured';
 });
},
4
barnski

Vous devez retourner un Promise à partir de orderEmployees

orderEmployees: companyId => User.find({ companyId }).exec()

Si vous souhaitez effectuer un traitement des erreurs ou un pré-traitement avant de les renvoyer, vous pouvez conserver votre code tel quel, mais n'oubliez pas de renvoyer le résultat (les promesses peuvent être chaînées).

3
James