【问题标题】:How to pass a third argument to a callback using Bluebird.js nodeify如何使用 Bluebird.js nodeify 将第三个参数传递给回调
【发布时间】:2014-07-18 04:56:52
【问题描述】:

With a little help我已经到了以下代码来承诺a passport.js login strategy.

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var Promise = require('bluebird');
var bcrypt = require('bcrypt');
var db = require('./db').db; //users are stored in mongo

//I'm using bluebird.js for promises
var users = Promise.promisifyAll(db.users);
var compare = Promise.promisify(bcrypt.compare);


// This strategy is used by passport to handle logins
module.exports.localStrategy = new LocalStrategy(function(username, password, done) {
  users.findOneAsync({username: username}).bind({})
    .then(function(user) {
        if (!user) {
          throw new NoMatchedUserError('Incorrect username.');
          //should be equivalent to:
          // return done(null, false, {message:'something'});
        }
        this.user = user;
        return compare(password, user.password);
    })
    .then(function(isMatch) {
      if (isMatch) {
        return this.user;
        //is equivalent to:
        // return done(null, this.user);
      }
      else {
        throw { message: 'Incorrect password.' };
        //should be equivalent to:
        // return done(null, false, {message:'something else'};
      }
    })
    .nodeify(done);
});

通过调用nodeify(done),我可以处理密码匹配的路径,但我不知道如何传递可选的第三个参数以便passport.js 可以使用它。

是否可以处理两个失败(不是错误)路径?


更新:

根据 cmets 的要求,我在 Github 上创建了一个问题,并且(非常迅速地)在 Bluebird v2.0 中添加了此功能

https://github.com/petkaantonov/bluebird/issues/219

【问题讨论】:

  • 哇,这实际上是 nodeify 的一个很好的用例,很多节点 API 需要多个参数。打开一个问题,我们会处理它(意思是,我会在他写之前给 petka 出问题,如果他不写,我会写它,他会重写它以提高性能)ץ
  • 嗯,您的原始代码实际上看起来还不错。您需要一个可以解决三种可能状态的 Promise:错误、已识别用户和登录问题。您可以尝试不同的错误类型,它们的处理方式不同,但您不能在这里简单地使用nodeify
  • @BenjaminGruenbaum 我看不出这怎么可能,如果你用数组解决承诺,你怎么知道 nodeify 应该用数组作为结果调用它还是为 nodeback 传播数组? Passport 在这里违反了节点回调约定并查看结果:P
  • @Esailija 一个解决方案是第二个参数。
  • @BenjaminGruenbaum 听起来像脚枪

标签: javascript node.js promise passport.js bluebird


【解决方案1】:

我添加这个答案是为了展示如何在原始示例中使用.nodeify(done, {spread: true})(如其他答案/cmets 中所述)。

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var Promise = require('bluebird');
var bcrypt = require('bcrypt');
var db = require('./db').db; //users are stored in mongo

//I'm using bluebird.js for promises
var users = Promise.promisifyAll(db.users);
var compare = Promise.promisify(bcrypt.compare);

// This strategy is used by passport to handle logins
module.exports.localStrategy = new LocalStrategy(function(username, password, done) {
  users.findOneAsync({username: username}).bind({})
    .then(function(user) {
        if (!user) {
          return [false, { message: 'Incorrect username.' }]; <---------------
          //should be equivalent to:
          // return done(null, false, {message:'something'});
        }
        this.user = user;
        return compare(password, user.password);
    })
    .then(function(isMatch) {
      if (isMatch) {
        return this.user;
        //is equivalent to:
        // return done(null, this.user);
      }
      else {
        return [false, { message: 'Incorrect password.' }]; <---------------
        //should be equivalent to:
        // return done(null, false, {message:'something else'};
      }
    })
    .nodeify(done, {spread: true});
});

【讨论】:

    【解决方案2】:

    用途:

    .nodeify(done, {spread: true});
    

    这允许将多个参数传递给“完成”回调。

    更多信息:

    Bluebird nodeify documentation

    【讨论】:

    【解决方案3】:

    目前.nodeify没有办法,你当然可以手动使用.then

    .then(function(result){
         done(/*whatever arguments you need*/);
    },function(failure){
         done(/* failure argumnets */);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 2015-11-13
      • 2021-10-19
      • 2015-11-12
      • 1970-01-01
      • 2010-11-14
      • 1970-01-01
      相关资源
      最近更新 更多