【发布时间】:2016-07-12 05:45:57
【问题描述】:
假设我有一个条件语句,之后创建了一个 Promise。我想创建一个共享的.catch() 函数,每次我的任何承诺失败时都会调用该函数。但是,如果我稍后附加 catch 语句 - 它们会被区别对待,为什么?
var p1;
var condition = true;
if (condition) {
p1 = new Promise(function(resolve, reject) {
setTimeout(function() { reject('BREXIT!'); }, 1000);
});
} else {
p1 = new Promise(function(resolve, reject) {
setTimeout(function() { resolve('REMAIN!'); }, 1000);
});
}
p1.catch(function(e) { console.error("1 I CATCH", e); } );
p1.catch(function(e) { console.error("2 I CATCH", e); } );
p1.then(function(e) { console.log("ALL DONE"); } );
// Actual output:
//
// 1 I CATCH BREXIT!
// 2 I CATCH BREXIT!
// Uncaught (in promise) BREXIT!
//
//==============================
// Expected output:
//
// 1 I CATCH BREXIT!
// ALL DONE
你可以在这里玩这个代码:http://jsbin.com/lopuyid/edit?js,console
我明白我可以通过将整个 Promise 创建移动到单独的函数并链接所有内容来解决这个问题。我的问题是为什么.catch() 语句实际上并没有捕捉到任何东西并且被执行all,而不是一个?链接A.f1().f2() 和链接A.f1(); A.f2() 不一样吗?
更新
如果有人通过网络搜索访问此页面,请阅读此帖子下的精彩链接。为了快速解决问题,无需太多代码更改,您应该在每次 catch 之后更新相同的 promise,然后:
p1 = p1.catch(function(e) { console.error("1 I CATCH", e); } );
p1 = p1.catch(function(e) { console.error("2 I CATCH", e); } );
p1 = p1.then(function(e) { console.log("ALL DONE"); } );
【问题讨论】:
-
你在同一个 Promise 上注册了多个处理程序。如果该 Promise 被拒绝,则同一 Promise 上的所有
.catch()处理程序都将被调用,并且不会在该 Promise 上调用任何解析处理程序。它们就像事件处理程序。同一个 Promise 上的所有事件处理程序都会被调用。一个不影响另一个。这是分支。您要问的是链接。试试p.catch().catch()。那是链接,并且会以不同的方式工作。第一个.catch()处理程序将影响第二个链接。 -
“链接 A.f1().f2() 和做 A.f1(); A.f2() 不一样吗?”。 - 不,这不对。链接时,f1() 将返回一个带有添加行为(catch)的全新承诺,这会影响 f2()。
-
见Chaining vs. Branching 和Stacks vs. Chaining。这个
p.then(...); p.then(...)与p.then(...).then(...)完全不同。 -
除了@jfriend00,我想指出两个
catch处理程序完美地捕捉到了被拒绝的Promise。未捕获的Promise是由第三个then处理程序引起的。但是你当然可以链接一个 catch 处理程序:p1.then(function(e) { console.log("ALL DONE"); } ).catch(() => console.log("BREXIT IS THE WRONG DECISION"));. -
感谢大家指点我这些帖子。学到了很多!老实说,我尝试寻找答案,但未能在谷歌搜索中正确表达自己:) 第一次听到带有承诺的“分支”一词......
标签: javascript promise branch chaining