【问题标题】:Express does not wait for the promise快递不等承诺
【发布时间】:2020-12-09 06:13:15
【问题描述】:
router.post('/login', async (req, res) => {

  await Auth.findOne({ userEmail }, { userLoginInfo: 0 }).then((auth) => {
    console.log('1');
    console.log(res.header); <---------- header sent after console.log('1')
    // Check if user exists
    if (auth === null) {
      return res
        .status(400)
        .json({ authFailedMessage: 'Email or password is incorrect' });
    } else if (auth !== null) {
      console.log('auuuuuuth')
      console.log(res.header)
      console.log('auuuuuuth13412312')
      bcrypt.compare(password, auth.password).then((isMatch) => {
        if(isMatch) {
          console.log(res.header)
          console.log('matched!')
          console.log(res.header)
        } else if (!isMatch) {
          console.log(res.header)
          console.log('hhhhh?!')
          console.log(res.header)
        }
      })

我正在尝试验证用户,然后在 cookie 中发送 jwt。但是,即使在我对结果做一些事情之前, res 标头也会触发。我尝试过使用 new Promise(),但是,在这种情况下,它在 Promise 返回值后不会继续。对已返回的 mongoose 查询结果执行操作后,如何发送标头?

-----新代码

router.post('/login', async (req, res) => {
  const logInEnvironment = browser(req.headers['user-agent']);
  const ipAddress = requestIp.getClientIp(req);
  const userEmail = req.body.userEmail.toLowerCase();
  const password = req.body.password;
  console.log('aa')
  console.log(res.header);
  // Form validation
  const validation = await validateLoginInput(req.body);
  console.log(res.header);
  console.log('ab')
  // Check validation
  if (!validation.isValid) {
    return res.status(400).json(validation.errors);
  }
  console.log(res.header);
  console.log('ac')
  // Find user by email

  const auth = await Auth.findOne({ userEmail }, { userLoginInfo: 0 })
    console.log(`auuuuth? ${auth}`);
    console.log(res.header);
    console.log('ad')

    if(auth !== null) {
      console.log('ahiuhiuhaisudf!')
    } else {
      console.log('whaitoh!?')
    }
 
});

------控制台日志

aa
[Function: header]
a <------ from 'const validation = await validateLoginInput(req.body)'
[Function: header]
ab
[Function: header]
ac
auuuuth? {
  termsandconditions: {
    agreed: true,
  },

}
[Function: header]
ad
ahiuhiuhaisudf!

【问题讨论】:

  • 编写一个中间件可以解决这个问题
  • 代码中的问题到底在哪里?您当前在问题中的代码发送的唯一响应是错误响应。其他代码路径不发送任何响应。那么,你在哪里等待承诺?仅供参考,await 永远不会等待像bcrypt.compare() 使用的普通回调。 await 只等待承诺。我不确定这是否与您的问题有关,因为我不知道您的问题到底是什么/在哪里。
  • 这就是我的想法。我尝试附加带有返回值的 cookie 标头,但是,正如我在代码中标记的那样,响应是在执行 console.log('1') 之后立即发送的。我认为这就是为什么我不断收到“标头已发送后无法发送标头”错误的原因。我是菜鸟,所以我真的不知道为什么它返回 console.log(res)

标签: node.js express mongoose


【解决方案1】:

关于您如何“等待”承诺,您的代码存在问题。在使用 await 关键字时,您似乎在 Promise 中附加了 .then(),它们的用途相同。

await Auth.findOne({ userEmail }, { userLoginInfo: 0 }).then((auth) => {

您应该尝试删除 .then() 块并将已解决的承诺存储在变量中:

const auth = await Auth.findOne({ userEmail }, { userLoginInfo: 0 });
//Do what you want with the 'auth' here

如果这有帮助,请告诉我。

【讨论】:

  • 我将代码更改为先返回标题。我刚刚添加了新代码 + 返回 console.log。
  • 我不明白你的问题到底是什么,但如果你想设置标题,请使用res.set(field [, value]),如快递documentation中所述。
  • 我想发送 cookie(其值来自 Promise)。而且, res.cookie 没有工作,因为标头已经发送。
猜你喜欢
  • 2019-02-18
  • 2017-03-04
  • 2016-02-26
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多