node.js - Mongoose Promise 未填充到脚本中
问题描述
我有一个 api 服务器和一些脚本作业。他们使用相同的功能来使用 mongoose 拉出名册并填充名册中的球员。在api服务器上,这个函数是正常调用的。使用脚本,它不会。
API 示例
function getRoster(id) {
var deferred = Q.defer();
Roster.find({_id:id}, 'playerRoster userId tournamentId').populate('playerRoster').exec(
function(err, roster) {
if (err) {
deferred.resolve(err);
}
deferred.resolve(roster[0]);
});
return deferred.promise;
}
api.post('/get_roster', function(req, res) {
// get tournament
var id = req.body._id;
var playerId = req.body.playerId;
getRoster(id).then(function(data) {
var roster=data;
res.json(roster);
});
});
脚本
module.exports = function(config) {
this.getRoster=function(id) {
//return Roster.find({_id:id}, 'playerRoster userId tournamentId').exec( - THIS RETURNS
return Roster.find({_id:id}, 'playerRoster userId tournamentId').populate('playerRoster').exec(
function(err, roster) {
if (err) {
return err;
}
console.log('roster[0]',roster);
return roster[0];
});
}
this.tallyPoints = function(tournamentPlayer,sportsPlayers) {
var deferred = Q.defer();
var totalPoints =0;
console.log("tallyPoints 0 ",tournamentPlayer);
var rosterId = tournamentPlayer.player.roster[0];
console.log("tallyPoints 1 ",rosterId);
this.getRoster(rosterId).then(function(roster2){
console.log("tallyPoints 2 ",roster2);
...
deferred.resolve(totalPoints);
});
return deferred.promise;
}
return this;
};
在脚本中,记录 roster[0] 或 tallyPoints 2 行都不会打印,但也没有错误。
为什么我添加填充时 Roster.find 不返回?我唯一能想象的是因为 playerRoster 集合有 2000 条记录搜索 ~10 并且它遇到了一些没有被捕获的超时。
任何清理它的建议也值得赞赏。谢谢
解决方案
Moongoose 长期支持 Promise。在需要 promise 的地方使用基于回调的 Mongoose API 是不合适的,并且Q.defer
与现有的 promise 一起使用被称为 Deferred 反模式(类似地,new Promise
会导致 promise 构造反模式)。
在其当前状态下getRoster
,不会返回承诺,也不会正确处理错误。
function getRoster(id) {
return Roster.find({_id:id}, 'playerRoster userId tournamentId').populate('playerRoster').exec()
.then(roster => roster[0]);
}
api.post('/get_roster', function(req, res) {
// get tournament
var id = req.body._id;
var playerId = req.body.playerId;
getRoster(id)
.then(function(data) {
var roster=data;
res.json(roster);
})
.catch(err => {
// handle error
});
});
考虑到 onlyroster[0]
被使用,它可能应该改为Roster.findOne
.
无论getRoster
是在 Express 路线还是其他地方使用都没有关系,它应该可以工作。未知module.exports = function(config) {...}
模块是如何使用的,但this
如果它不用作类,可能会引用错误的上下文。如果不使用getRoster
,它们不应驻留在此函数中。tallyPoints
config
推荐阅读
- c++ - 用于读取复数的 c++ 正则表达式
- android - Websocket 在“101 Switching Protocols”响应中关闭与 EOF 异常的连接
- c - 函数参数接收一个 int "b" 数字但打印一个随机数(函数调用函数)
- ruby-on-rails - Rails 5.2 Auth - create_new_auth_token 后返回的令牌
- google-cloud-platform - 是否有用于 google 语音到文本的语言支持的 API?
- java - 如何使用毕加索从 .mp3 文件中检索专辑封面
- android - React-Native - Firebase 云消息传递 - 如果从托盘打开则没有事件
- c# - 将 2 个 datagridview 分组列减去第三列
- python - 为什么在编写二叉搜索树时会出错?
- sql-server - 如何使用 T-SQL 解码 base64 unicode 字符串