Использование мангуста 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()