await действителен только в асинхронной функции - nodejs - PullRequest
0 голосов
/ 23 апреля 2019

Я использую узел и экспресс для создания сервера для моего приложения. Вот как выглядит мой код:

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 Ответ

2 голосов
/ 23 апреля 2019

Вам не хватает асинхронного объявления для одной из ваших функций.Вот рабочий код:

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

Ваш ответ будет отправлен еще до того, как вы совершите вызов базы данных, потому что вы не заключаете в файл response.send внутри .then.Вы можете переместить response.send в .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'); 
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...