【问题标题】:Mongoose async/await questions猫鼬异步/等待问题
【发布时间】:2020-10-16 06:56:14
【问题描述】:

您好,我正在调试我的应用程序但卡住了,我认为关于如何在异步函数中正确处理 mongoose,我还没有完全掌握。

所以我的主 server.js 有类似的东西

  const user = await userService.authenticate({ username, password });
  console.log("user in the main method is ...");
  console.log(user);

我还有另一个“userService.js”,类似于(简化)

async function authenticate({ username, password }) {  
  await Users.find({ username: username, password: password }, function(
    err,
    user
  ) {
    if (err) res.send(err);
    if (user) {

      console.log("user within the authenticate method is...  ");
      console.log(user);
      return user;
    }
  });
}

问题出在authenticate 方法中,console.log 具有正确的身份验证信息,但是在主 server.js 中我得到了不同的值。我怀疑这与我使用 async 和 await 关键字的方式有关。这是我从控制台得到的结果

user within the authenticate method is...  
[
  {
    _id: 5ee845ee39fdf73190068308,
    username: 'XXXXXX',
    firstName: 'XXX',
    lastName: 'XXX',
    password: 'XXX',
    categoryDiscount: [ [Object], [Object] ]
  }
]
user in the main method is ...
undefined

【问题讨论】:

    标签: node.js mongoose promise async-await


    【解决方案1】:

    有趣的是,在将身份验证方法修改为以下内容后,我让它工作了。

    async function authenticate({ username, password }) {
      console.log("starting the authenticate method");
      const user = await Users.findOne({ username: username, password: password });
      if (user) {
        console.log("user within the authenticate method is...  ");
        console.log(user);
        return user;
      }
    }
    
    

    但目前尚不清楚为什么这种变化会使事情奏效......

    【讨论】:

    • 这意味着 Users.findOne 支持承诺。您正在使用回调,需要承诺与 async/await 一起使用。你可以看到我的承诺验证()的答案,但这个选项更干净
    【解决方案2】:

    await 键盘只能在 async 函数中使用。不能在外面使用。

    async function authenticate({ username, password }) {
    Users.find({ username: username, password: password }, function(err, user) {
        if (err) res.send(err);
          return user;
        }
      });
    }
    
    async function print() {
        const user = await userService.authenticate({ username, password }); 
        console.log(user)
    }
    print()
    

    这将打印所需的结果。

    【讨论】:

    • 对不起,我没有澄清 - server.js 中的 await 也在异步函数中。
    【解决方案3】:

    在 main.js 中使用 await 是可以的,缺少的是您需要在 authenticate() 中返回一个 Promise。您不需要使 authenticate() 异步。

     function authenticate({ username, password }) {
      return new Promise((res, rej) => {
        Users.find({ username: username, password: password }, function(err, user) {
          if (err) {
            // res.send(err);
            rej(err); // this error will need to be caught using try/catch in calling function
          } else {
            // we resolve the promise as long as no error was returned
    
            console.log("user within the authenticate method is...  ");
            console.log(user);
            //return user;
            res(user); // user returned to calling function
          }
        });
      });
    }
    

    【讨论】:

      【解决方案4】:

      Await 用于等待承诺解决。它不会返回或停止函数的执行。这里authenticate 函数不返回任何内容。 V8 知道这是一个承诺,但由于没有返回,从await userService.authenticate({ username, password }); 解析的值将是undefined。使用此逻辑,则以下代码将起作用

      function authenticate({ username, password }) {
        return Users.findOne({ username: username, password: password })
      }
      // or
      async function authenticate({ username, password }) {
        const user = await Users.findOne({ username: username, password: password })
        return user
      
      }
      // or 
      function authenticate({ username, password }) {
        return new Promise((resolve,reject) => {
           Users.findOne({ username: username, password: password },function(err,user) 
             {
                if(err) return reject(err)
                return resolve(user)
      
             })
        })
      }
      

      【讨论】:

        猜你喜欢
        • 2018-08-30
        • 1970-01-01
        • 2019-05-10
        • 2021-04-20
        • 2018-04-13
        • 2019-02-15
        • 2018-06-11
        • 2020-08-01
        • 2019-12-12
        相关资源
        最近更新 更多