【问题标题】:SailsJS Waterline with Bluebird PromisesSailsJS 水线与蓝鸟承诺
【发布时间】:2015-06-05 05:55:31
【问题描述】:

使用水线 ORM 时,如果我想使用默认提供的 bluebird promise api,如何将处理传递回控制器。

下面是代码:

module.exports = {
    //Authenticate
    auth: function (req, res) {
        user = req.allParams();
        //Authenticate
        User.authenticate(user, function (response) {
            console.log(response);
            if (response == true) {
                res.send('Authenticated');
            } else {
                res.send('Failed');
            }
        });
    }
};


module.exports = {
    // Attributes

    // Authenticate a user
    authenticate: function (req, cb) {
        User.findOne({
            username: req.username
        })
        .then(function (user) {
            var bcrypt = require('bcrypt');
            // check for the password
            bcrypt.compare(req.password, user.password, function (err, res) {
                console.log(res);
                if (res == true) {
                    cb(true);
                } else {
                    cb(false);
                }
            });
        })
        .catch(function (e) {
            console.log(e);
        });
    }
};

我只是想实现一个身份验证功能。业务逻辑是直截了当的。我感到困惑的是从那以后请求流是如何交回控制器的。如果我尝试返回响应,则承诺不会响应,但执行 cb(value) 是有效的。

【问题讨论】:

标签: node.js sails.js waterline


【解决方案1】:

使用 Promise 的关键是永远不要破坏链条。 Promise 链依赖于每一步返回一个promise或一个值,或者抛出一个错误。

以下是对您的代码的重写。请注意

  • 路径中的每个回调都返回一些东西,每个函数都返回它所使用的承诺链(甚至是 .auth();它可能在某些时候有用)
  • 我用 BlueBird 的 .promisifyAll() 让 bcrypt 一起玩
  • 我已经通过明确 username 和 password 参数将 .authenticate() 与您的请求/响应基础架构分离。这样可以更轻松地重复使用。

所以现在我们已经(不是 100% 测试,我没有费心安装水线):

module.exports = {
    // authenticate the login request
    auth: function (req, res) {
        var params = req.allParams();
        return User.authenticate(params.username, params.password)
        .then(function () {
            res.send('Authenticated');
        })
        .fail(function (reason) {
            res.send('Failed (' + reason + ')');
        });
    }
};

和

var Promise = require("bluebird");
var bcrypt = Promise.promisifyAll(require('bcrypt'));

module.exports = {
    // check a username/password combination
    authenticate: function (username, password) {
        return User.findOne({
            username: username
        })
        .then(function (user) {
            return bcrypt.compareAsync(password, user.password)
        })
        .catch(function (err) {
            // catch any exception problem up to this point
            console.log("Serious problem during authentication", err);
            return false;
        })
        .then(function (result) {
            // turn `false` into an actual error and
            // send a less revealing error message to the client
            if (result === true) {
                return true;
            } else {
                throw new Error("username or password do not match");
            }
        });
    }
};

【讨论】:

  • 这解决了我对 Promise 的很多疑问。 +1
  • 它们需要一些时间来适应,但之后它们就是一个漂亮的工具。与节点的原生回调架构相比,各方面都更好。
  • 这不应该也返回一个promise而不是true/false吗?我想否则,您无法在 Controller 或 http 级别的某个地方执行实际回调,因此这将是一个同步调用。
  • 承诺不一定要返回承诺。您可以直接返回一个值,这就是它的全部意义所在。我不太明白你说的“否则没有回调”是什么意思?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-24
  • 2014-02-13
  • 2014-11-06
  • 2015-09-06
  • 2015-02-13
相关资源
最近更新 更多