web-dev-qa-db-ja.com

async / awaitでのMongoose Promiseの使用

Node.jsのasync/await機能でMongoose Promiseを使用しようとしています。関数printEmployeesが呼び出されたときに、orderEmployees関数によって照会された従業員のリストを保存します。 orderEmployees内のconsole.logステートメントは期待されるクエリを返しますが、printEmployees内のconsole.logundefinedを返し、約束を正しく返していないことを示唆します。

私はパラダイムを正しく理解していないほど完全に可能な約束をするのは初めてです...どんな助けも大歓迎です。

  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

returnPromiseする必要があります。そうでない場合は、undefinedを返す関数を待っています。

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

現在、非プロミスを待っているため、次のコードが実行されますimmediately;約束の前に、あなたが本当に待ちたいのは実際に解決します。

また、本当に重要.catchハンドラーでthrowの代わりにreturnを使用する必要があります。

18
Nik Kyriakides

orderEmployeesを非同期関数のように動作させるには、結果のプロミスを返す必要があります。 async/awaitキーワードなしでpromiseを使用する場合に従うべき2つのルールがあります。

  1. Promiseを返す場合、関数は非同期です
  2. プロミス(たとえば、非同期関数によって返される)がある場合は、.thenを呼び出すか、返す必要があります。

async/awaitを使用している場合、取得するプロミスでmustawaitを使用します。

これは、orderEmployees内で生成されたプロミスを返さないことに気付くということです。修正は簡単ですが、その関数を非同期に書き換えることも簡単です。

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';
  });
},

または

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

PS:エラー処理はここでいくらか欠陥があります。通常、関数からエラー文字列を返すことでエラーを処理しません。この場合、エラーを伝播し、トップレベルのUIコードからエラーを処理することをお勧めします。

24
Tamas Hegedus

OrderEmployeesからPromiseを返していません。

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

PromiseからorderEmployeesを返す必要があります

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

戻る前にエラー処理または前処理を行いたい場合は、コードをそのまま保持できますが、結果を返すことを忘れないでください(約束は連鎖可能です)。

3
James