Использование мангуста promises с асинхронным/ожиданием

Я пытаюсь использовать Mongoose promises с асинхронными/ожидающими функциями Node.js. Когда вызывается моя функция printEmployees, я хочу сохранить список сотрудников, которые запрашиваются функцией orderEmployees. В то время как оператор console.log внутри orderEmployees возвращает ожидаемый запрос, console.log внутри printEmployees возвращает undefined, предполагая, что я не верну свое обещание правильно.

Я новичок в promises настолько полностью, что я не правильно понимаю парадигму... любая помощь очень ценится.

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

Ответ 1

Вам необходимо return ваше Promise, иначе вы ожидаете функцию, которая возвращает undefined.

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

В настоящее время вы ожидаете не-Promise, поэтому следующий код будет запущен немедленно; прежде чем обещание, которое вы действительно хотите ждать, на самом деле разрешится.

Также очень важно, вы должны throw вместо return в свой обработчик .catch.

Ответ 2

Чтобы заставить orderEmployees вести себя как функции async, вы должны вернуть полученное обещание. При использовании promises без async/await ключевых слов следует соблюдать два правила:

  • Функция является асинхронной, если она возвращает Promise
  • Если у вас есть обещание (например, возвращено функцией async), вы должны либо вызвать .then на нем, либо вернуть его.

Когда вы используете async/await, вы получаете должен await на promises.

Это говорит о том, что вы не вернете обещание, сгенерированное внутри 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: здесь некорректная обработка ошибок. Обычно мы не обрабатываем ошибки, возвращая строку ошибки из функции. Лучше иметь распространение ошибки в этом случае и обрабатывать ее с помощью некоторого кода верхнего уровня, кода пользовательского интерфейса.

Ответ 3

Вы не возвращаете Promise от 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

Вам нужно вернуть Promise из orderEmployees

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

Если вы хотите выполнить некоторую обработку ошибок или предварительную обработку перед возвратом, вы можете сохранить свой код как есть, но просто не забудьте вернуть результат (promises являются цепями).

Ответ 5

Пожалуйста, помогите мне мой код. Возвращает имя {}

  let timetableFunc = (name) => {
                        let a = timetable.find({ sectionID: name }).exec()
                        return a.then(result => {
                            if (result[0] !== undefined) {
                                console.log(result[0])
                              return result[0]
                            } 
                        })
                    }

                    let asyncf = async () => {

                        let arr = await sections[0].section.map(sect => {
                            let name = timetableFunc(sect.name);
                             console.log('name is ${JSON.stringify(name)}');
                        })

                    }

                    asyncf()