异步等待使用身份验证之前,不能让服务器等待数据库的响应

时间:2019-07-01 19:27:42

标签: javascript express asynchronous async-await

所以我遇到了一个问题,我试图对数据库进行异步调用,以检查帐户的用户名和密码是否存在,然后再检查它们是否有效。

我遇到了一个问题,即服务器跳过了我的数据库调用,然后继续进行检查,然后再获取数据库中的信息。

代码:

class HandlerGenerator {
  login (req, res) {
    let username = req.body.username;
    let password = req.body.password;
    let checkUsername = "";
    let checkPassword = "";

    var lData = {
        username: req.body.username,
        password: req.body.password
      };
    // For the given username fetch user from DB
    var db = req.db;
    var getUser = async () => {
        var result = await (
          User.findOne(lData , function(err, userLogin){
              if(err){
                console.log(err);
                return
              }
              console.log(userLogin);
              console.log("------====----");
              console.log(userLogin.username);
              checkUsername = userLogin.username;
              checkPassword = userLogin.password;

              console.log("------====----");
              console.log(checkUsername);
              console.log(checkPassword);
            })
        );
        console.log("--00--");
        console.log('result' + result)
        return result;
    };

    console.log("does this work?");
    if (username && password) {
      console.log("------==2==----");
      console.log(checkUsername)
      console.log(checkPassword)
      if (username === checkUsername && password === checkPassword) {
        let token = jwt.sign({username: username},
          config.secret,
          { expiresIn: '24h' // expires in 24 hours
          }
        );
        // return the JWT token for the future API calls
        res.json({
          success: true,
          message: 'Authentication successful!',
          token: token
        });
      } else {
        res.send(403).json({
          success: false,
          message: 'Incorrect username or password'
        });
      }
    } else {
      res.send(400).json({
        success: false,
        message: 'Authentication failed! Please check the request'
      });
    }
  }
  index (req, res) {
    res.json({
      success: true,
      message: 'Index page'
    });
  }
}

当我运行此程序时,“此功能有效吗?”评论总是首先出现,我对自己搞砸的事情感到困惑

1 个答案:

答案 0 :(得分:1)

您在这里有两个主要问题。

首先,async返回一个AsyncFunction,在被调用时返回一个Promise。这意味着在这一点上,getUser中的任何内容都没有执行。不仅需要实际调用getUser来开始运行其中的内容,而且还需要等待结果,否则,您完全不能保证执行将结束。 除了尝试解决此麻烦之外,使login函数async似乎是一个更合理的选择,因为您正在尝试在其中执行异步操作。然后,您可以删除getUser函数,而仅保留var result = await User.findOne(....)部分。

正如多人在评论中所述,另一个问题是您需要await Promise上。 查看您的函数调用,您的findOne函数似乎使用了回调而不是诺言。请检查文档,某些库同时支持这两个库,并且如果您不传递任何回调,则可能确实返回了Promise。 如果是这样,则不应传递任何回调。 “等待”调用的结果应为userLogin

否则,包装函数以使其返回promise很简单。 基本模式如下

// this is the function that we want to wrap
function funcToWrap(someParam, callback) {
   // does stuff
   callback(null, "some result");
}

// this is the wrapper
function wrappedFunction(someParam) {
  return new Promise((resolve, reject) => {
    funcToWrap(someParam, (err, res) => {
      if (err === null) {
        reject(err);
      } else {
        resolve(res);
      }
    });
  });

这会将基于回调的函数转换为基于承诺的函数。然后,您当然可以在await上使用wrappedFunc并将其用作任何其他promise。

这是一种常见的模式,许多库已经实现了此功能。例如,Promise库Bluebird提供了一个promisify函数,正是此函数。 http://bluebirdjs.com/docs/api/promise.promisify.html

因此,您不必自己编写所有这些内容,而只需编写

var wrappedFunction = Promise.promisify(funcToWrap);