【问题标题】:Bluebird promise as callback for promise unaware apiBluebird Promise 作为 Promise unaware api 的回调
【发布时间】:2015-11-23 02:26:50
【问题描述】:

我想向护照的完成回调函数传递一个承诺。如果我使用 bluebird promise 库,我将如何处理?

我知道有一个承诺主题,有一个 asCallbackfromCallback,但我无法从示例中理解。

exports.signup = new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
  },
  (req, email, password, done) => {
    ...
    return done(null, false, {type: 'warning', message: 'Email is in use.'})
    ...
  }
);

编辑:

这是我想要达到的目标:

exports.signup = new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true,
  passportLocalCallback
});

function passportLocalCallback(req, email, password, done) {
  return new Pormise((resolve, reject) => {
    return User.findOneAsync({email: email});
  })
  .then((existingUser) => {
    if (existingUser) {
      resolve([null, false, {type: 'warning', message: 'That email is already taken.'}])
    }
    return User.generateHash(password);
  })
  .then((hash) => {
    return User.createAsync({
      email: email,
      password: hash
    })
  })
  .catch((err) => reject(err));
}

【问题讨论】:

  • 我不确定这是否可行,因为 Passport 要求使用特定参数调用 done()(如果身份验证成功,则表示用户的对象,如果不成功,则表示虚假)。您能否详细说明您想要做什么(例如,承诺来自哪里)。
  • @robertklep 我更新了这个问题,希望现在更清楚了。我很确定这可以使用 bluebird promisification 工具来完成,但不清楚如何。
  • new Pormise((resolve, reject) => { return User.findOneAsync({email: email}); }) 肯定是错误的。不仅因为错字,还因为你不能从构造函数回调中返回任何东西。
  • 啊,我明白了,所以在构造函数 cb 中我不需要使用 return,因为无论如何它都会在第一个 then 中。

标签: node.js promise passport.js bluebird


【解决方案1】:

我不认为你可以使用 Promisification 工具让它工作,主要是因为 Passport 也有一个有效的 3 参数回调情况,这是 Bluebird 不知道的(我认为)。

目前我能想到的唯一解决方案:

function passportLocalCallback(req, email, password, done) {
  User.findOneAsync({ email : email }).then((existingUser) => {
    if (existingUser) {
      return done(null, false, {type: 'warning', message: 'That email is already taken.'});
    }
    return User.generateHash(password).then( (hash) => {
      return User.createAsync({
        email    : email,
        password : hash
      })
    }).then( (user) => {
      return done(null, user);
    });
  }).catch((err) => done(err));
}

编辑:使用 asCallback() 会稍微缩短代码,但 IMO 并没有那么混乱:

function passportLocalCallback(req, email, password, done) {
  User.findOneAsync({ email : email }).then((existingUser) => {
    if (existingUser) {
      return [ false, { type: 'warning', message: 'That email is already taken.' } ];
    }
    return User.generateHash(password).then( (hash) => {
      return User.createAsync({
        email    : email,
        password : hash
      })
    });
  }).asCallback(done, { spread : true });
}

(未经测试)

【讨论】:

  • 但这意味着我将不得不在许多情况下将回调风格与承诺混合在一起,我认为这会造成很多混乱。我希望asCallback 的用例能够解决这样的情况。并且还有多个参数的扩展选项。 bluebirdjs.com/docs/api/ascallback.html
  • @AttilaEgyed 我编辑了我的答案以使用asCallback()
猜你喜欢
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
  • 2017-02-25
  • 2014-05-10
  • 1970-01-01
  • 2015-03-04
  • 2019-10-15
  • 2017-03-27
相关资源
最近更新 更多