【问题标题】:Nest multiple async await嵌套多个异步等待
【发布时间】:2018-10-22 01:08:12
【问题描述】:

我有以下 Express 端点:

const all = require('promise-all');

router.post('/verify', upload.single('photo'), async (req, res) => {
  ...    
  await all({'p1': p1, 'p2': p2}).then((response) => {
      ...
      console.log("Response:", 
      ruleCtrl.manageRule(detection, res);
  });
});

ruleCtrl.manageRule如下:

export async function manageRule(identifierDetected, res) {
  let rule = db.getRule(identifierDetected);
  await all([rule]).then((ruleExtracted) => {
    ...
    res.json(ruleExtracted);
  }).catch((err) => {
    res.status(418).send("DOCUMENT_NOT_RECOGNIZED");
  });
}

db.getRule:

export async function getRule(idRule) {
  return new Promise((resolve, reject) => {
    Rule.findOne({ruleID: idRule}, (err, rule) => {
        if (err) {
            reject("MongoDB Rule error: " + err);
        } else {
            resolve(rule);
        }
    });
  })
}

我的回复是到manageRule,这个函数取决于提取到await all 中的值。所以,现在,Express 在从 mongoose 数据库 (db) 获取信息之前返回一个响应。

解决这个问题的方法是什么?

谢谢大家!

【问题讨论】:

  • 是“db.getRule(identifierDetected);”异步?
  • await all.then() 没什么意义。如果您要使用.then(),请不要使用await。或者,在没有.then() 的情况下执行let results = await all(...),然后在下一行代码中使用results。选择一种风格或另一种风格。您正在使用await,但没有利用您使用await 的原因。这是没有意义的。要么利用它的优势,要么不使用它。
  • @Faheem 更新了我的帖子。
  • Promise.all() 与一个promise 一起使用也是没有意义的。
  • @jfriend00 我已经删除了最后一个等待(同意你的观点。它没有意义),但结果相同......

标签: node.js express async-await


【解决方案1】:

我会稍微重构您的代码以使其更易于阅读,并返回来自ruleCtrl.manageRule(detection, res); 的结果。 该请求可能只是超时,因为您的原始代码在那里缺少返回或等待(以确保它完成执行)

快递端点:

const all = require('promise-all');

router.post('/verify', upload.single('photo'), async (req, res) => {
  ...
  // Catch any exceptions from the promises. This is the same as using .catch
  try {
    // Lets assign the returned responses to variable
    let [p1Result, p2Result] = await all({'p1': p1, 'p2': p2});
    ...
    console.log("Responses:", p1Result, p2Result);
    // return the response from manageRule method
    return ruleCtrl.manageRule(detection, res);
  } catch(err) {
    // Handle err here
  }
});

async await 的一大好处是摆脱了链式 Promise,因此只需将 await 的结果返回到变量,而不是使用 .then()

ruleCtrl.manageRule

export async function manageRule(identifierDetected, res) {
  // Use try catch here to catch error from db.getRule. Assign to variable and return 
  // res.json  
  try {      
    let ruleExtracted = await db.getRule(identifierDetected);
    ...
    return res.json(ruleExtracted);
  } catch(err) {
    return res.status(418).send("DOCUMENT_NOT_RECOGNIZED");
  }
}

你不必在这里返回res.jsonres.status,我只是想跟踪我什么时候想要结束函数执行。

您可以进一步重构ruleCtrl.manageRule 方法,方法是不将res 作为参数发送,而是从db.getRule 返回结果。让router.post('/verify) 处理req 和res,这样更容易阅读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-25
    • 2020-10-17
    • 2018-06-04
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    相关资源
    最近更新 更多