首页 文章

Javascript async等待等待mongoose等待

提问于
浏览
2

我试图从我的控制器中移出数据库调用来清理并使它们可测试 . 当他们在控制器中时,一切都很顺利 . 我将它们移出控制器并添加了异步以确保我们等待 . 否则,我会在 Users.findOne().exec() 内调用 res.render() 函数 . 现在,一旦我使用async / await,我的控制器中的函数认为没有用户,因为它没有等待 .

有关异步等待的SO有几个问题,但我没有找到解决我的问题的问题 . 我确实验证了我的用户已退回,并且我添加了控制台日志以显示路径 .

  • node mongoose async await似乎很有希望,但他们的实际问题是未能退回该项目,而我的回报很好

  • async not waiting for await与kotlin有关

  • async await not waiting似乎非常适用,但我完全不了解嵌套await / async的答案 - 提问者的问题比我的查询更复杂,因为他们正在处理循环和forEach

  • Javascript async await是现货,所以我检查了mongoose函数返回一个promise . Mongoose文档显示它已准备好进行异步,因为调用会返回一个promise .

假设我们正在解决路线问题 /users

路线/ index.js

// requires & other routes not shown 
router.get('/users', controller.testUserShow);

控制器/ index.js

// requires & other routes not shown 
   exports.testUserShow = async (req, res, next) => {
      if (req.user) { // if code to get user is right here, with no async/await, the user is found and the code continues
        try {
          found = await services.fetchUser(req.user._id)
          console.log("I am not waiting for at testusershow")
          console.log(found); //undefined
          // go on to do something with found
        } catch(e) {
          throw new Error(e.message)
        }
      }
    }

服务/ index.js

const db = require('../db')
exports.fetchUser = async (id) => {
  try {
    console.log("fetchUser is asking for user")
    return await db.returnUser(id)
  } catch(e) {
    throw new Error(e.message)
  }
}

DB / index.js

const User = require('../models/user');
exports.returnUser = async (id) => {
  User.findById(id)
      .exec(function(err, foundUser) {
          if (err || !foundUser) {
              return err;
          } else {
              // if this was in the controller 
              // we could res.render() right here
              console.log("returnUser has a user");
              console.log(foundUser); // this is a User
              return foundUser;
          }
      });
}

控制台日志

fetchUser is asking for user
I am not waiting for at testusershow
undefined
returnUser has a user
// not printed... valid user

如果我调用的东西没有返回一个承诺,我会期望初始调用是未定义的,但 User.findOne() 应该 .

What am I missing here?

2 回答

  • 4

    这是最简单的方法:

    const User = require('../models/user');
    exports.returnUser =  (id) => {
       return User.findById(id).exec().then(foundUser => { 
              console.log(foundUser); // this is a User
              return foundUser;
      });
    }
    

    如果你想使用async / await那么你可以这样做:

    exports.returnUser = async id => {
           const foundUser = await User.findById(id).exec();
           console.log({foundUser});
           return foundUser;
          });
        }
    

    如果你想使用回调,它看起来像:

    exports.returnUser =  (id, cb) => {
       return User.findById(id).exec(cb);
    }
    

    很酷的想想Mongoose是如果你没有传递一个回调,它将从exec函数/方法返回一个promise .

  • 1

    你的 db/index 应该是这样的:

    exports.returnUser = (id) => {
      return User.findById(id);
    }
    

    当你不调用exec时,它将返回一个promise . 并且由于 services/index.js 已经使用 await 来获取响应, db/index 不需要是异步函数 .

相关问题