node.js 使代码同步的中间件

node.js middleware making code synchronous

我正在努力让 res.locals.info 在每个页面上都可用。 我正在尝试通过中间件执行此操作,但出现错误。 显然 res.locals.info 在页面呈现时还没有准备好,因此我得到一个错误 info is not defined。我该如何解决?

  app.use(function(req,res,next){

  async function getInfo(user) {

    let result = await info.search(user);
    setInfo(result);
  }

function setInfo(result){

  res.locals.info= result;
}
getInfo(req.user);

  return next();
})

搜索():

module.exports.search= function (user) {
    var query=`SELECT count(*) as Info from dbo.InfoUsers WHERE user= '${user}' ;`

    return new Promise((resolve, reject) => {
    sequelize
        .query(`${query}`, {model: InformationUser})
        .then((info) => {

        resolve(info);
        })
    })
};

您在 getInfo() 函数完成其工作之前调用了 next(),因此当您尝试使用它时 res.locals.info 尚未设置。

一个async函数returns一个承诺。在 await 完成之前它不会阻塞。相反,它 returns 立即承诺。您将需要在 getInfo() 上使用 await.then(),以便您知道实际完成的时间。

如果 info.search() returns 一个解决了期望结果的承诺,那么你可以这样做:

app.use(function(req,res,next){

  // this returns a promise that resolves when it's actually done
  async function getInfo(user) {
    let result = await info.search(user);
    setInfo(result);
  }

  function setInfo(result){
    res.locals.info= result;
  }

  // use .then() to know when getInfo() is done
  // use .catch() to handle errors from getInfo()
  getInfo(req.user).then(result => next()).catch(next);

});

并且,您可以从搜索功能中删除 deferred anti-pattern 并修复错误处理(这是使用反模式时的常见问题)。无需将现有的承诺包装在另一个承诺中。:

module.exports.search = function (user) {

    var query=`SELECT count(*) as Info from dbo.InfoUsers WHERE user= '${user}' ;`
    // return promise directly so caller can use .then() or await on it
    return sequelize.query(`${query}`, {model: InformationUser});
};