英文:
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));
英文:
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));
答案3
得分: 0
可取消的承诺在ECMAScript中不受支持,但您可以根据错误参数的类型有条件地处理catch子句。例如,假设您知道每个真实的错误参数都是非空的。然后您可以:
- 在记录或处理真实错误后,在catch处理程序中抛出
null
。 - 在每个catch处理程序的开头检查
err
参数,看它是否为null
。如果是,立即重新抛出null
错误值。 - 在承诺链的末尾,放置一个额外的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
- Throw
null
in a catch handler after logging or processing a real error. - Check if the
err
argument at the beginning of every catch handler to see if it isnull
. If so, re-throw the null error value immediately. - 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论