从承诺中回报承诺

时间:2015-05-04 00:31:39

标签: javascript promise

我想知道如何从承诺中回报承诺。 E.g。

我有这样的结构:

doAsyncStuff()  // a promise
  .then( function(res) {
    doAnotherAsyncStuff(res)  // another promise
      .then( makeSomeThings )
      .then( function(anotherRes, opts) {
        ...
      })
    })
  .then( ... )

我想这样写:

doAsyncStuff()  // a promise
  .then( function(res) {
    doAnotherAsyncStuff(res)  // another promise
      .then( makeSomeThings )
      // and somehow push-out promise
  })
  .then( function(anotherRes) {
     ...
  })
  .then( ... )

我怎样才能达到这样的效果?

问题

var Promise = require('bluebird');
//noinspection JSUnresolvedFunction
var bcrypt = Promise.promisifyAll(require('bcrypt'));
var Sequelize = require('sequelize');
var config = require('config');

var sequelize = new Sequelize(config.get('db.connstring'));


//noinspection JSUnresolvedFunction
var User = sequelize.define('user', {
  name: {
    type: Sequelize.STRING
  },
  email: {
    type: Sequelize.STRING,
    validate: {
      isEmail: true
    }
  },
  passwordHash: {
    type: Sequelize.STRING
  },
  isConfirmed: {
    type: Sequelize.BOOLEAN,
    allowNull: false,
    defaultValue: false
  }
}, {
  freezeTableName: true,
  classMethods: {
    login: Promise.method(function (email, password) {
      if (!email || !password) throw new Error('Email and password are both required');
      var rv = this
        .find({where: {email: email.toLowerCase().trim()}})
        .then(function (user) {

          return bcrypt.compareAsync(password, user.passwordHash).then(function (res) {
            console.log(email, password, res);
          });
          // if i dont use pacthed compare here, i have no problem ..
          // return bcrypt.compare(password, user.passwordHash, function(err, res) {
          //    console.log(email, password, res);
          //  });
        });
      console.log('B', rv);
      return rv;
    })
  }
});

sequelize.sync({force: true}).then(function () {
  var pwd = 'pwd';
  //noinspection JSUnresolvedFunction
  bcrypt.hashAsync(pwd, 4).then(function (salt) {
    var u1 = User.create({
      name: 'u1',
      email: 'u1@ex.com',
      passwordHash: salt
    }).then(function (result) {
      User.login('u1@ex.com', pwd).then(function (res) {
        console.log('A', res)
      })
    });
  });
});

3 个答案:

答案 0 :(得分:5)

回复你的另一个承诺

doAsyncStuff()  // a promise
  .then( function(res) {
    return doAnotherAsyncStuff(res)  // another promise
  })
  .then( function(anotherRes) {
     ...
  })
  .then( ... )

答案 1 :(得分:2)

如果一个函数表示将前一个(已解决的)结果转换为下一个结果一个将解析为下一个结果的promise,则只需将其传递给{{1直接。

then

在这里演示:http://jsfiddle.net/Lzxtuu1b/

答案 2 :(得分:0)

正如其他答案已经建议的那样,您必须从return回调中 then 。无论你返回一个简单的价值还是一个价值的承诺都没关系,两者都有效;但是当你什么也没有返回时,结果的承诺将通过undefined来解决。

在您的特定示例中,它位于:

doAsyncStuff()  // a promise
  .then( function(res) {
    return doAnotherAsyncStuff(res)  // another promise
//  ^^^^^^
      .then( makeSomeThings )
   …

…
  .then(function (user) {
      return bcrypt.compareAsync(password, user.passwordHash).then(function (res) {
        console.log(email, password, res);
        return res;
//      ^^^^^^
      });

在您的上一个示例中,当您使用return时,您甚至可以unnest拨打电话:

var pwd = 'pwd';
sequelize.sync({force: true}).then(function () {
  //noinspection JSUnresolvedFunction
  return bcrypt.hashAsync(pwd, 4);
}).then(function (salt) {
  return User.create({
    name: 'u1',
    email: 'u1@ex.com',
    passwordHash: salt
  });
}).then(function (result) {
  return User.login('u1@ex.com', pwd);
}).then(function (res) {
   console.log('A', res);
});