Mongoose Promise 的异步性
Posted
技术标签:
【中文标题】Mongoose Promise 的异步性【英文标题】:Asynchronicity of a Mongoose Promise 【发布时间】:2018-05-01 10:34:59 【问题描述】:首先,请原谅我有点模棱两可的标题;我找不到更合适的:
场景
我正在使用 Mongoose 获取一些数据,然后使用 ejs 渲染它们。为了便于说明,请考虑以下几点:
// Schema
var UserSchema = mongoose.Schema(
Username: String,
City: String
)
// Model
var User = mongoose.model('User', UserSchema);
来自我的服务器文件:
app.get('/view', function (req, res)
// What I am trying to do
User.find().exec().then(vals=>
res.send(vals)
)
问题
上述代码按预期工作,但对于其他文件可访问的代码以及使升级更容易,我想将其移动到另一个文件,然后 require() 该文件。
handler.js
// Promise: Get All Names
function FetchData()
return User
.find()
.exec();
module.exports =
Get: function()
val = User.find().exec()
.then(vals=>
// Expected to return only after the above is complete
return vals
)
然后,从我的服务器文件中:
var handler = require('handler')
app.get('/view', function (req, res)
res.send(handler.Get())
);
很遗憾,此代码无法按预期工作
我的想法
我改变了参数并调整了代码几次,但无法弄清楚出了什么问题。 似乎 Get() 的值甚至在承诺被消耗之前就被返回了(这令人费解)。
非常欢迎任何帮助:)
【问题讨论】:
你仍然不能在 promise 回调的外部函数中return
。您需要返回 promise 对象本身,并在调用者处使用 then
使用其结果。 Promise 不会使您的代码同步,它们不会使未来的值立即可用!
有解决办法吗?
没有。在您发明时间机器之前,没有任何解决方法。
【参考方案1】:
我觉得你应该是这样的:
module.exports =
Get: function()
return User.find().exec()
.then(vals =>
// Expected to return only after the above is complete
return vals
)
然后
app.get('/view', function (req, res)
handler.Get().then((response) =>
res.send(response);
);
);
所以,从Get
返回承诺,然后使用它的then
API。
【讨论】:
建议的代码不起作用:TypeError: Cannot read property 'then' of undefined 错误表示您没有将return
添加到Get
。还要检查更新的代码。
问题依旧:/
你会想要drop the pointless .then(vals => vals)
【参考方案2】:
这里的代码可以帮助你。
把你的主服务器文件改成这样的
app.get('/view', function (req, res)
handler.Get().then(vals =>
res.send(vals);
);
在 handler.js 文件中,你可以这样做
module.exports.Get = function()
return new Promise((resolve, reject) =>
User.find().exec(function(err, users)
if(!err)
resolve(users);
);
);
【讨论】:
以上是关于Mongoose Promise 的异步性的主要内容,如果未能解决你的问题,请参考以下文章
[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist