为什么`.catch()`没有捕获任何内容并且多次执行?

时间:2016-07-12 05:45:57

标签: javascript promise branch chaining

假设我有一个条件语句,之后会创建一个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()语句实际上没有捕获任何内容并执行全部而不是一个?不是将A.f1().f2()链接到与A.f1(); A.f2()相同的内容吗?

更新

如果有人通过网络搜索访问此页面,请阅读此帖子下的精彩链接。要快速解决问题,无需更改代码,您应该在每次捕获后更新相同的承诺,然后:

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"); } );

1 个答案:

答案 0 :(得分:0)

从您的代码中,您期望的是第一次出现reject时,1 I CATCH BREXIT!应该出现。如果它第二次出现2 I CATCH BREXIT!应该出现。但这不是javascript的工作原理。它基于事件,您可以为事件注册多个操作。

基本上,通过这样做:

p1.catch(function(e) { console.error("1 I CATCH", e); } );
p1.catch(function(e) { console.error("2 I CATCH", e); } );

您注册了2个独立事件,这些事件会在reject上触发。