最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Return promise from promise - Stack Overflow

programmeradmin0浏览0评论

I wonder how to return promise from promise. E.g.

I have such construction:

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

I want to write it like this:

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

How can I achieve such result?

the problem thing

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 bcryptpareAsync(password, user.passwordHash).then(function (res) {
            console.log(email, password, res);
          });
          // if i dont use pacthed pare here, i have no problem ..
          // return bcryptpare(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: '[email protected]',
      passwordHash: salt
    }).then(function (result) {
      User.login('[email protected]', pwd).then(function (res) {
        console.log('A', res)
      })
    });
  });
});

I wonder how to return promise from promise. E.g.

I have such construction:

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

I want to write it like this:

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

How can I achieve such result?

the problem thing

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.pareAsync(password, user.passwordHash).then(function (res) {
            console.log(email, password, res);
          });
          // if i dont use pacthed pare here, i have no problem ..
          // return bcrypt.pare(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: '[email protected]',
      passwordHash: salt
    }).then(function (result) {
      User.login('[email protected]', pwd).then(function (res) {
        console.log('A', res)
      })
    });
  });
});
Share Improve this question edited May 4, 2015 at 1:02 akaRem asked May 4, 2015 at 0:31 akaRemakaRem 7,6484 gold badges31 silver badges44 bronze badges 1
  • Here is a good article about promises, if you want to figure out: pouchdb./2015/05/18/we-have-a-problem-with-promises.html – Andrew Commented Feb 6, 2016 at 12:22
Add a ment  | 

3 Answers 3

Reset to default 5

Just return your other promise

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

If a function represents the transformation of the previous (resolved) result to either the next result, or a promise which will resolve to the next result, you just need to pass it to then directly.

function return1() {
    return Promise.resolve(1);
}

function wait(ms) {
    return new Promise(function (resolve) {
        setTimeout(resolve, ms);
    });
}

function increment(val) {
    return wait(1000).then(function () {
        return val + 1;
    });
}

function square(val) {
    return wait(1000).then(function () {
        return val * val;
    });
}

var p = return1()
    .then(increment)
    .then(square); // Returns a promise that will resolve to 4 (eventually)

p.then(function (result) { console.log(result); });

Demo here: http://jsfiddle/Lzxtuu1b/

As the other answers already suggested, you must return from your then callbacks. Whether you return a plain value or a promise for a value doesn't matter, both will work; but when you return nothing then the resulting promise will be resolved with undefined.

In your particular examples, it is here:

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

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

An in your last example, you can even unnest al lot calls when you use return:

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: '[email protected]',
    passwordHash: salt
  });
}).then(function (result) {
  return User.login('[email protected]', pwd);
}).then(function (res) {
   console.log('A', res);
});
发布评论

评论列表(0)

  1. 暂无评论