如何在 Promise.catch 中提前退出 Promise.then 链?

huangapple go评论57阅读模式
英文:

How can I exit early from a chain of Promise.then in Promise.catch?

问题

这是我的代码 (在JSFiddle上查看):

fetch('https://some.invalid.url').then(resp => resp.text())
.catch(err => console.log("got error: " + err))
.then(text => console.log("got text: " + text));

目前这会记录两行:

"got error: TypeError: Failed to fetch"
"got text: undefined"

我希望它只记录这一行:

"got error: TypeError: Failed to fetch"

换句话说,我希望一旦调用了.catch,就结束Promise链而不进入.then。我该怎么做?

(我可以在.catch内部抛出异常,但我认为这会导致一个不希望发生的unhandledrejection事件)。

英文:

I have this code (view on JSFiddle):

fetch('https://some.invalid.url').then(resp => resp.text())
.catch(err => console.log("got error: " + err))
.then(text => console.log("got text: " + text));

Currently this logs the two lines

"got error: TypeError: Failed to fetch"
"got text: undefined"

I would like it to only log the line

"got error: TypeError: Failed to fetch"

In other words, I would like the promise chain to end once the .catch is called and not go into the .then. How can I do this?

(I could throw an exception inside the .catch, but I think that results in a unhandledrejection event which is undesirable).

答案1

得分: 2

你的问题是你的.catch()返回了一个已解决的Promise(以console.log()的返回值解决,即undefined)。

要么将.catch()移到承诺链的末尾:

fetch('https://some.invalid.url').then(resp => resp.text())
.then(text => console.log("got text: " + text))
.catch(err => console.log("got error: " + err));

要么让它继续拒绝该链(但请注意,这将引发未捕获的Promise拒绝错误):

fetch('https://some.invalid.url').then(resp => resp.text())
.catch(err => {
  console.log("got error: " + err);
  return Promise.reject(err);
})
.then(text => console.log("got text: " + text));
英文:

Your issue is that your .catch() returns a resolved promise (resolving with the return value of console.log(), ie undefined).

Either move the .catch() to the end of the promise chain

fetch('https://some.invalid.url').then(resp => resp.text())
.then(text => console.log("got text: " + text))
.catch(err => console.log("got error: " + err));

or have it continue rejecting the chain (but note this will throw an uncaught promise rejection error)

fetch('https://some.invalid.url').then(resp => resp.text())
.catch(err => {
  console.log("got error: " + err);
  return Promise.reject(err);
})
.then(text => console.log("got text: " + text));

答案2

得分: 1

你需要交换顺序,使.catch()位于链的末尾。

fetch('https://some.invalid.url').then(resp => resp.text())
.then(text => console.log("获取文本应该失败:" + text))
.catch(err => console.log("获取错误应该失败:" + err));


fetch('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js').then(resp => resp.text())
.then(text => console.log("获取文本应该成功:" + text))
.catch(err => console.log("获取错误应该成功:" + err));

在JSFiddle上查看

英文:

You need to swap the ordering so the .catch() is at the end of the chain.

fetch('https://some.invalid.url').then(resp => resp.text())
.then(text => console.log("got text should fail: " + text))
.catch(err => console.log("got error should fail: " + err));


fetch('https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js').then(resp => resp.text())
.then(text => console.log("got text that should succeed: " + text))
.catch(err => console.log("got error should succeed: " + err));

(view on JSFiddle)

答案3

得分: 0

可取消的承诺在ECMAScript中不受支持,但您可以根据错误参数的类型有条件地处理catch子句。例如,假设您知道每个真实的错误参数都是非空的。然后您可以:

  1. 在记录或处理真实错误后,在catch处理程序中抛出null
  2. 在每个catch处理程序的开头检查err参数,看它是否为null。如果是,立即重新抛出null错误值。
  3. 在承诺链的末尾,放置一个额外的catch处理程序,如果其参数不是 null,则重新抛出该参数 - 以报告开发期间未捕获的错误。

潜在地,这可以用于解决JS中可取消承诺的缺失问题 - 但我不建议在没有迫切需要的情况下使用它。正如评论中所建议的,将catch处理程序移动到链的末尾,或在同一个catch处理程序中记录错误并重新抛出错误是更常见的方法。

英文:

Cancellable promises are not supported in ECMASCRIPT, but you could process catch clauses conditionally upon the type of error argument. E.G. Say you know every real error argument is non-null. Then you could

  1. Throw null in a catch handler after logging or processing a real error.
  2. Check if the err argument at the beginning of every catch handler to see if it is null. If so, re-throw the null error value immediately.
  3. At the end of the promise chain, put an additional catch handler that re-throws its argument if it is not null - to report uncaught errors during development.

Potentially this could be used to work around the absence of cancellable promises in JS - but I do not suggest using it without dire need. As comments have suggested, moving catch handlers to the end of the chain, or logging an error and re-throwing it in the same catch handler is the more common approach.

huangapple
  • 本文由 发表于 2023年6月22日 10:54:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76528323.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定