当 Node 必须进行任何 I/O 时,例如从数据库中读取,它将异步完成。像User.findOne 和Query#exec 这样的方法永远不会预先返回结果,因此article.owner 在您的示例中不会正确地未定义。
异步查询的结果仅在您的回调中可用,该回调仅在您的 I/O 完成时调用
article.owner = User.findOne({ name : 'ABC' }) .exec(function (err, user){
// User result only available inside of this function!
console.log(user) // => yields your user results
})
// User result not available out here!
console.log(article.owner) // => actually set to return of .exec (undefined)
在上面的例子中异步代码执行意味着什么:当 Node.js 命中 article.owner = User.findOne... 时,它将执行 User.findOne().exec(),然后在 .exec 完成之前直接移动到 console.log(article.owner)。
希望这有助于澄清。习惯异步编程需要一段时间,但多练习就会有意义
更新要回答您的具体问题,一种可能的解决方案是:
User.findOne({name: 'ABC'}).exec(function (error, user){
article.owner = user._id; // Sets article.owner to user's _id
article.save() // Persists _id to DB, pass in another callback if necessary
});
如果您想像这样向用户加载文章,请记住使用Query#populate:
Article.findOne({_id: <some_id>}).populate("owner").exec(function(error, article) {
console.log(article.owner); // Shows the user result
});