使用与异步/等待的mongoose promises

时间:2017-09-27 20:54:56

标签: javascript node.js asynchronous promise

我正试图通过Node.js的async / await功能来使用Mongoose promises。当我的函数printEmployees被调用时,我想保存orderEmployees函数查询的员工列表。虽然console.log内的orderEmployees语句会返回预期的查询,但console.log内的printEmployees会返回undefined,这表明我没有正确地返回承诺

我很容易接受承诺,以至于我无法正确理解范式......我们非常感谢任何帮助。

  printEmployees: async(company) => {
    var employees = await self.orderEmployees(company);
    // SECOND CONSOLE.LOG
    console.log(employees);
  },

  orderEmployees: (companyID) => {
    User.find({company:companyID})
    .exec()
    .then((employees) => {
      // FIRST CONSOLE.LOG
      console.log(employees);
      return employees;
    })
    .catch((err) => {
      return 'error occured';
    });
  },

5 个答案:

答案 0 :(得分:20)

为了使orderEmployees表现得像异步函数,您必须返回结果承诺。使用没有async/await关键字的承诺时,要遵循两条规则:

  1. 如果函数返回Promise
  2. ,则该函数是异步的
  3. 如果您有一个承诺(例如由异步函数返回),您必须在其上调用.then或将其返回。
  4. 当您使用async/await时,必须 await您获得的承诺。

    这表示你会注意到你没有返回orderEmployees内生成的承诺。易于修复,但也很容易将该功能重写为异步。

    orderEmployees: (companyID) => {
      return User.find({company:companyID}) // Notice the return here
      .exec()
      .then((employees) => {
        // FIRST CONSOLE.LOG
        console.log(employees);
        return employees;
      })
      .catch((err) => {
        return 'error occured';
      });
    },
    

    orderEmployees: async(companyID) => {
      try {
        const employees = await User.find({company:companyID}).exec();
        console.log(employees);
        return employees;
      } catch (err) {
        return 'error occured';
      }
    },
    

    PS:错误处理在这里有些缺陷。我们通常不会通过从函数返回错误字符串来处理错误。最好在这种情况下传播错误,并从一些顶级UI代码处理它。

答案 1 :(得分:13)

您需要return Promise,否则您正在等待返回undefined的函数。

orderEmployees: (companyID) => {
  return User.find({ company:companyID }).exec()
}

目前,您正在等待非承诺,因此下一行代码将立即运行 ;在Promise之前,你真的想等待实际解决。

答案 2 :(得分:4)

您没有从orderEmployees返回Promise。

printEmployees: async(company) => {
  var employees = await self.orderEmployees(company);
  // SECOND CONSOLE.LOG
  console.log(employees);
},

orderEmployees: (companyID) => {
  return User.find({company:companyID})
 .exec()
 .then((employees) => {
   // FIRST CONSOLE.LOG
   console.log(employees);
   return employees;
 })
 .catch((err) => {
   return 'error occured';
 });
},

答案 3 :(得分:2)

您需要从Promise

返回orderEmployees
orderEmployees: companyId => User.find({ companyId }).exec()

如果你想在返回之前做一些错误处理或预处理,那么你可以保持你的代码不变,但只记得返回结果(承诺是可链接的)。

答案 4 :(得分:1)

如果您要使用异步/等待,则它的工作原理如下。

  • 在返回承诺的函数之前等待。
  • 包装功能前的异步。
  • 将函数体包装在try / catch块中。

请看一下这个功能,它是一个中间件 在我执行Express中的特定路线之前。

const validateUserInDB = async (req, res, next) => {
    try {
        const user = await UserModel.findById(req.user._id);
        if (!user) return res.status(401).json({ message: "Unauthorized." });
        req.user = user;
        return next();
    } catch (error) {
        return res.status(500).json({ message: "Internal server error." })
    }
}
  • 等待后的代码正在等待承诺得到解决。
  • catch块会捕获try块中发生的任何错误,即使catch方法触发的错误来自等待诺言。