嵌套多个异步等待

时间:2018-10-21 16:09:04

标签: node.js express async-await

我有以下Express端点:

OtherScript

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现在正在返回响应。

哪种方法可以处理此问题?

谢谢大家!

1 个答案:

答案 0 :(得分:1)

我将对您的代码进行一些重构,使其更易于阅读,并从ruleCtrl.manageRule(detection, res);返回结果。

您的原始代码缺少返回或等待(确保完成执行)的请求,因此请求可能只是超时了

Express端点:

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

异步await的一大好处是摆脱了链式承诺,因此只需将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,以便使其更易于阅读。