JavaScript 承诺:链接承诺混乱
JavaScript Promises: Chaining promise confusion
我一直在玩 Promises,下面示例中的链接没有 return 预期的结果。
getHeroChain()
函数按预期工作,但 getHeroUnChain()
函数没有。在这两种情况下,执行顺序都符合预期,但是在 getHeroUnChain()
中,最后一个 then
函数没有 return 预期值(HEROES
数组)。
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();
getHeroChain()
的输出:
1) inside setTimeout
2) setTimeout resolved
2) inside 1st 'then' with value : 2
3) inside final 'then' with heroes : [Object, Object]
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
这是因为你 return mainPromise
在 getHerosSlowlyUnchained
。每次调用 then
或类似方法 return 都是链中的 new 承诺。
在getHeroChain
中,你的链是:setTimeout
-> setTimeout resolved
-> final then
.
在 getHeroUnChain
你的链是:setTimeout
-> [setTimeout resolved
, final then
].
请注意,在第二个示例中,setTimeout resolved
和 final then
都在 setTimeout
之后。这意味着两者都给出了 2
.
要修复,要么做
return mainPromise.then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
或
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;
.then()
总是生成一个新的承诺,所以在你的 UnChained 函数中,你应该 return 新的承诺,而不是旧的 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;
}
我一直在玩 Promises,下面示例中的链接没有 return 预期的结果。
getHeroChain()
函数按预期工作,但 getHeroUnChain()
函数没有。在这两种情况下,执行顺序都符合预期,但是在 getHeroUnChain()
中,最后一个 then
函数没有 return 预期值(HEROES
数组)。
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();
getHeroChain()
的输出:
1) inside setTimeout
2) setTimeout resolved
2) inside 1st 'then' with value : 2
3) inside final 'then' with heroes : [Object, Object]
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
这是因为你 return mainPromise
在 getHerosSlowlyUnchained
。每次调用 then
或类似方法 return 都是链中的 new 承诺。
在getHeroChain
中,你的链是:setTimeout
-> setTimeout resolved
-> final then
.
在 getHeroUnChain
你的链是:setTimeout
-> [setTimeout resolved
, final then
].
请注意,在第二个示例中,setTimeout resolved
和 final then
都在 setTimeout
之后。这意味着两者都给出了 2
.
要修复,要么做
return mainPromise.then(function(value) {
console.log(" 2) setTimeout resolved");
console.log(" 2) inside 1st 'then' with value : " + value);
return getHeros(); //return promise
});
或
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;
.then()
总是生成一个新的承诺,所以在你的 UnChained 函数中,你应该 return 新的承诺,而不是旧的 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;
}