如何使用 Bluebird 处理 Mongoose 返回的承诺?

How to handle promise returning with Mongoose using Bluebird?

我有一个 Account 模式,用 Mongoose 定义,我用 Bluebird 设置了承诺:

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

我已经为这样的模式设计了一个模型方法:

accountSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.password);
}

所以我找到了一个方法来尝试查找用户并检查密码是否匹配:

function login (email,password) {

    return Account.findOne({email: email}).then(function (user) {
        console.log(user);
        user["match"] = user.validPassword(password);
        console.log(user);
        return user.validPassword(password);
    });
}

真正奇怪的是,第二个 console.log 不会显示对象的任何 match 属性。

我的目的是return承诺找到用户并检查密码匹配,但是当我调用登录时:

login("email","password").then(function(user){...})

用户没有匹配项属性,我该如何实现?

login(email,password){
    return new Promise(function(resolve,reject){
        Account.findOne({email: email}).then(function (user) {
            user.match = user.validPassword(password);
            resolve(user)
        });

    })
}

您不能在调用 Promise 调用之前同时执行 return :return Account.xxxxx AND 执行 .then() 。 ......它是一个或......我给你两种选择。版本 A 我们处理本地登录功能的结果集:

function login (email,password) {

    // notice I no longer have return Account.xxxx
    Account.findOne({email: email}) // Account.findOne returns a Promise
    .then(function (user) {

        if (user) {

            user.match = user.validPassword(password);
            // execute some callback here or return new Promise for follow-on logic

        } else {
            // document not found deal with this
        }

    }).catch(function(err) {

        // handle error
    });
}

来电者是这样的:

login("email","password") // needs either a cb or promise
.then(function(userProcessed) { ... 
}).

... 而在版本 B 中,我们将处理委托给调用者来执行 .then() 逻辑:

function login (email,password) {

    return Account.findOne({email: email});
}

所以在来电者中我们有:

login("email","password").then(function(userNotProcessed){...})

findOne 获得结果集后,对 user 执行一些验证,避免假设它已找到。 此外,由于 Promise 现在在 ES6 中,您可以使用内置的 Promise 实现

mongoose.Promise = global.Promise;

请注意,findOne return 是一个文档,而 find 总是给你一个包含 0 个或更多文档的数组