Node.js 猫鼬承诺不会在脚本中填充

Node.js 猫鼬承诺不会在脚本中填充,node.js,mongoose,Node.js,Mongoose,我有一个api服务器和一些脚本作业。他们使用相同的功能使用mongoose拉取名册并填充名册中的球员。 在api服务器上,通常会调用此函数。使用脚本,它不会 API示例 function getRoster(id) { var deferred = Q.defer(); Roster.find({_id:id}, 'playerRoster userId tournamentId').populate('playerRoster').exec( function

我有一个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;

};
在脚本中,不会打印花名册[0]或tallyPoints 2行的日志记录,但也不会出现错误

为什么我添加时花名册.查找返回?我能想象的唯一一件事是,playerRoster集合有2000条记录在搜索~10条,但它遇到了一些未被捕获的超时

任何清理建议也将不胜感激。
感谢月亮鹅长期以来对承诺的支持。在需要承诺的情况下,使用基于回调的Mongoose API是不合适的,对现有承诺使用
Q.defer
称为延迟反模式(类似地,
newpromise
会导致承诺构造反模式)

在其当前状态下,
getrolister
不会返回承诺,也不会正确处理错误

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
    });
});
考虑到只使用了
花名册[0]
,可能应该将其更改为
花名册.findOne


无论
getrolister
是用于快速路线还是其他地方,它都应该有效。尚不知道如何使用
module.exports=function(config){…}
module,但是
this
如果不将其用作类,则可能引用错误的上下文。如果
getrolister
tallyPoints
不使用
config
,则它们不应驻留在此函数中。

建议在进一步移动之前清理控制流。你永远不需要问猫鼬。它已经兑现了承诺。这是promise构造反模式
如果(err){return err;}
-这是错误的,承诺应该被拒绝,这是它是反模式的众多原因之一。我理解你关于错误的意思。不过,api仍然有效。那么完全从名册中删除延迟?然后我无法调用getRosterI,我根据您的建议对脚本函数进行了更新,但在添加populate时仍然没有返回仍然存在问题。我举了一个应该如何做的例子。目前还不清楚您的案例中的确切问题是什么,但可能存在错误,您永远不会知道,因为错误没有得到处理。