【问题标题】:await is only valid in async function - nodejsawait 仅在异步函数中有效 - nodejs
【发布时间】:2019-09-12 22:31:27
【问题描述】:

我正在使用 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。我在这里做错了什么?

【问题讨论】:

  • function(err) { 应该是async ?
  • 我相信toArray 产生普通数组而不是数组的Promise,所以等待它对我来说真的没有意义。

标签: javascript node.js mongodb express async-await


【解决方案1】:

您的某个函数缺少异步声明。这是工作代码:

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 根据定义是异步的,因此必须使用回调或 Promise 范例。通过将函数声明为异步,您是在告诉 JavaScript 将您的响应包装在一个 Promise 中。您的问题在以下行:

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

【讨论】:

  • 感谢您的详细解答。当我尝试这个时,我在 xx 中得到一个空白数组。当我在 _prepareDetails 中执行 console.log(details) 时,我得到了正确的数据。但是当我在 let xx = await _prepareDetails(activityId,Id) 之后立即执行 console.log(xx) 时,它正在打印空数组。我尝试在 toArray 中移动 return 语句,但随后它打印出 undefined。
  • 您可能需要在聚合后删除 toArray 并调用 .exec。然后你 let xx = ... 你可以做 xx = xx.toArray
  • UnhandledPromiseRejectionWarning: TypeError: offer_collection.aggregate(...).exec 不是函数
  • 我对 Mongo 中的聚合函数不太熟悉,所以如果您遇到问题,可以再问一个问题
猜你喜欢
  • 2020-08-13
  • 2019-06-14
  • 1970-01-01
  • 2020-09-07
  • 1970-01-01
  • 2022-06-18
  • 2020-12-23
  • 2020-04-15
  • 1970-01-01
相关资源
最近更新 更多