【问题标题】:Why `.catch()` doesn't catch anything and is executed multiple times? [duplicate]为什么`.catch()` 没有捕获任何东西并且被多次执行? [复制]
【发布时间】: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. BranchingStacks 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


【解决方案1】:

根据您的代码,您期望的是,如果 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 上触发的独立事件。

【讨论】:

    猜你喜欢
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    相关资源
    最近更新 更多