【问题标题】:Bluebird promises returning too early in express/mongoose蓝鸟承诺过早返回快递/猫鼬
【发布时间】:2016-06-10 21:55:29
【问题描述】:

我不熟悉承诺,想知道为什么以下内容不起作用。我假设是因为我需要将自定义方法设置为使用 Promises 的特定方式。

我使用 bluebird 作为我的 Promise 库。我正在尝试通过在这些各自的模型(即讨论和用户模型)上使用猫鼬静态和方法来获取给定“用户”用户名的“讨论”对象列表。

下面是我在 Express 中的请求处理程序。现在只是尝试获取 JSON 并将其作为响应发送:

/* /routes/users.js */

var Promise = require('bluebird');
var User = require('../models/').User

/* ... express inclusions, other routes ... */

/* Get list of discussions for user */
router.get('/:username/discussions', function(req, res) {
    User.findOne({username: req.params.username}).then(function(user) {
        if (user) {
            return user.getDiscussions();
        } else {
            res.send('no user found');
        }
    }).then(function(discussions) {
        res.send(discussions);
    }).catch(function(error) {
        console.log('ERROR: ' + error);
        res.send('ERROR: ' + error);
    });
});

下面是user.getDiscussions():

/* /models/user.js */

var Promise = require('bluebird');
var mongoose = Promise.promisifyAll(require('mongoose'));
var Discussion = require('./discussion').Discussion;
var Schema = mongoose.Schema;

/* ... UserSchema defined here ... */

UserSchema.methods.getDiscussions = Promise.method(function() {
    var self = this;
    self.model('User').findById(self.id).then(function(user) {
        if (!user) {
            Promise.reject('User \'' + self.id + '\' does not exist.');
        } else {
            return Discussion.getDiscussionsForUser(self.username);
        }
    });
});

最后是 Discussion.getDiscussionsForUser:

/* /models/discussion.js */

var Promise = require('bluebird');
var mongoose = Promise.promisifyAll(require('mongoose'));
var Schema = mongoose.Schema;

/* ... DiscussionSchema defined here ... */

DiscussionSchema.statics.getDiscussionsForUser = Promise.method(function(username) {
    var self = this;
    self.model('User').findOne({username: username}, 'discussions').then(function(user) {
        if (!user) {
            return Promise.reject('User with username \'' + username + '\' does not exist.');
        } else {
            var discussions = [];
            return self.model('Discussion').find({
                '_id': { $in : user.discussions }
            });
        }
    });
});

似乎路由中的请求提前完成并在响应中发送未定义。知道为什么在 Discussion 模型中从 Mongoose 获得的讨论没有冒泡到路由吗?

【问题讨论】:

    标签: node.js express mongoose promise bluebird


    【解决方案1】:

    getDiscussions()getDiscussionsForUser() 没有正确返回承诺。更改它们如下:

    UserSchema.methods.getDiscussions = Promise.method(function() {
        var self = this;
        // *** added a return to this next line
        return self.model('User').findById(self.id).then(function(user) {
            if (!user) {
                // *** added a return to this next line
                return Promise.reject('User \'' + self.id + '\' does not exist.');
            } else {
                return Discussion.getDiscussionsForUser(self.username);
            }
        });
    });
    

    getDiscussionsForUser() 相同,应该是这样的:

    DiscussionSchema.statics.getDiscussionsForUser = Promise.method(function(username) {
        var self = this;
        // *** added a return to the next line
        return self.model('User').findOne({username: username}, 'discussions').then(function(user) {
            if (!user) {
                return Promise.reject('User with username \'' + username + '\' does not exist.');
            } else {
                var discussions = [];
                return self.model('Discussion').find({
                    '_id': { $in : user.discussions }
                });
            }
        });
    });
    

    为了使调用者能够使用 Promise 协调函数内异步操作的完成,通过该函数的所有代码路径必须始终从该函数返回一个 Promise。进入.then() 处理程序后,如果有进一步的嵌套异步操作,则必须返回一个承诺,或者如果您希望该值成为您所在的承诺的值,则可以只返回一个值。

    【讨论】:

    • 噢!谢谢...我已经研究了一段时间了,但是在最初找到用户之后,我太专注于每个功能的内部运作。
    猜你喜欢
    • 2015-10-27
    • 2015-11-19
    • 2016-09-23
    • 2015-03-06
    • 2016-06-04
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 2015-03-05
    相关资源
    最近更新 更多