#javascript #node.js #mongodb #express #async-await
#javascript #node.js #mongodb #выразить #async-await
Вопрос:
Я использую node и express для создания сервера для моего приложения. Вот как выглядит мой код:
async function _prepareDetails(activityId, dealId) {
var offerInfo;
var details = [];
client.connect(function(err) {
assert.equal(null, err);
console.log("Connected correctly to server");
const db = client.db(dbName);
const offers_collection = db.collection('collection_name');
await offers_collection.aggregate([
{ "$match": { 'id': Id} },
]).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
details = docs;
});
})
return details;
}
app.post('/getDetails',(request,response)=>{
var Id = request.body.Id;
var activityId = request.body.activityId;
_prepareDetails(activityId,Id).then(xx => console.log(xx));
response.send('xx');
})
При вызове getDetails
API я получаю
await is only valid in async function error (At line await offers_collection.aggregate)
Я также получаю красное подчеркивание при объявлении async function
. Версия узла, которую я использую, — 11.x. Я также использую firebase API. Что я здесь делаю не так?
Комментарии:
1.
function(err) {
должно бытьasync
?2. Я считаю, что
toArray
создать простой массив неPromise
из массива, поэтому ожидание этого на самом деле не имеет смысла для меня.
Ответ №1:
Вам не хватает объявления async в одной из ваших функций. Вот рабочий код:
async function _prepareDetails(activityId, dealId) {
var offerInfo;
var details = [];
client.connect(async function(err) {
assert.equal(null, err);
console.log("Connected correctly to server");
const db = client.db(dbName);
const offers_collection = db.collection('collection_name');
await offers_collection.aggregate([
{ "$match": { 'id': Id} },
]).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
details = docs;
});
})
return details;
}
app.post('/getDetails', async (request,response)=>{
var Id = request.body.Id;
var activityId = request.body.activityId;
let xx = await _prepareDetails(activityId,Id);
response.send('xx');
})
Await может использоваться только в асинхронной функции, потому что await по определению асинхронен и, следовательно, должен использовать парадигму обратного вызова или обещания. Объявляя функцию как асинхронную, вы указываете JavaScript обернуть ваш ответ в обещание. Ваша проблема заключалась в следующей строке:
client.connect(function(err) {
Именно здесь я добавил асинхронность, как упоминалось ранее.
client.connect(async function(err) {
Вы заметите, что я также сделал ваш маршрут асинхронным, потому что раньше у вас была бы проблема. Обратите внимание на две строки в вашем исходном коде:
_prepareDetails(activityId,Id).then(xx => console.log(xx));
response.send('xx');
Ваш ответ будет отправлен еще до того, как вы выполните вызов базы данных, потому что вы не завершаете ответ.отправить внутри .then. Вы могли бы переместить ответ.отправьте в .then , но если вы собираетесь использовать async / await, я бы использовал его полностью. Итак, ваш новый маршрут будет выглядеть так:
app.post('/getDetails', async (request,response)=>{
var Id = request.body.Id;
var activityId = request.body.activityId;
let xx = await _prepareDetails(activityId,Id);
response.send('xx');
})
Комментарии:
1. Спасибо за подробный ответ. Когда я пытаюсь это сделать, я получаю пустой массив в xx. Когда я создаю console.log (подробности) в _prepareDetails, я получаю правильные данные. Но когда я делаю console.log(xx) сразу после let xx = await _prepareDetails(ActivityId, Id), он печатает пустой массив. Я попытался переместить оператор return внутри toArray, но затем он печатает undefined.
2. Возможно, вам потребуется удалить toArray после aggregate и вызвать .exec. Затем после того, как вы дадите xx = … вы можете сделать xx = xx.toArray
3. Необработанное предупреждение promiserejectionwarning: TypeError: offers_collection.aggregate(…).exec не является функцией
4. Я не так хорошо знаком с агрегатными функциями в Mongo, поэтому вы можете задать другой вопрос, если у вас возникли проблемы