Reputation: 7618
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.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: '[email protected]',
passwordHash: salt
}).then(function (result) {
User.login('[email protected]', pwd).then(function (res) {
console.log('A', res)
})
});
});
});
Upvotes: 3
Views: 2771
Reputation: 664528
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.compareAsync(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);
});
Upvotes: 0
Reputation:
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.net/Lzxtuu1b/
Upvotes: 2
Reputation: 2696
Just return your other promise
doAsyncStuff() // a promise
.then( function(res) {
return doAnotherAsyncStuff(res) // another promise
})
.then( function(anotherRes) {
...
})
.then( ... )
Upvotes: 5