Reputation: 118
I've been playing with Promises and the chaining in the following example doesn't return the expected result.
The getHeroChain()
function works as expected, but the getHeroUnChain()
function doesn't. In both cases, the execution order is as expected, but, in getHeroUnChain()
, that last then
function doesn't return the expected value (the HEROES
array).
var HEROES = [{
id: 11,
name: 'Mr. Nice'
}, {
id: 12,
name: 'Narco'
}, ];
function getHeros() {
return Promise.resolve(HEROES); // resolved promise
}
function getHerosSlowlyChained() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(" 1) inside setTimeout");
resolve(2);
}, 2000);
}).then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
}
function getHerosSlowlyUnchained() { //not directly chained
var mainPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(" 1) inside setTimeout");
resolve(2);
}, 2000);
});
mainPromise.then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
return mainPromise;
}
//Chained
function getHeroChain() {
var heroPromise = getHerosSlowlyChained();
heroPromise.then(function(heroes) {
console.log(" 3) inside final 'then' with heroes :");
console.log(heroes);
});
}
//Un-Chained
function getHeroUnChain() {
var heroPromise = getHerosSlowlyUnchained();
heroPromise.then(function(heroes) {
console.log(" 3) inside final 'then' with heroes :");
console.log(heroes);
});
}
//getHeroChain();
getHeroUnChain();
Output of getHeroChain()
:
1) inside setTimeout
2) setTimeout resolved
2) inside 1st 'then' with value : 2
3) inside final 'then' with heroes : [Object, Object]
Output of getHeroUnChain()
:
1) inside setTimeout
2) setTimeout resolved
2) inside 1st 'then' with value : 2
3) inside final 'then' with heroes : 2
JSBIN link : https://jsbin.com/pivoyuyawu/edit?js
Upvotes: 0
Views: 604
Reputation: 21199
This is because you return mainPromise
in getHerosSlowlyUnchained
. Every call to then
or similar methods returns a new promise in the chain.
In getHeroChain
, your chain is: setTimeout
-> setTimeout resolved
-> final then
.
In getHeroUnChain
your chain is: setTimeout
-> [setTimeout resolved
, final then
].
Note that in the second example, both setTimeout resolved
and final then
are after setTimeout
. This means that both are given 2
.
To fix, either do
return mainPromise.then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
or
mainPromise = mainPromise.then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
return mainPromise;
Upvotes: 2
Reputation: 185
.then()
always generate a new promise, so in your UnChained function, you should return the new promise, instead of the old mainPromise
function getHerosSlowlyUnchained() { //not directly chained
var mainPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(" 1) inside setTimeout");
resolve(2);
}, 2000);
});
// this will generate a new promise, you should return the new one
// instead of the old mainPromise
mainPromise.then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
return mainPromise;
}
Upvotes: 0