我很难理解把 .catch
放在一起的区别。 BEFORE 和 AFTER then 在嵌套的 Promise 中。
备选方案 1:
test1Async(10).then((res) => {
return test2Async(22)
.then((res) => {
return test3Async(100);
}).catch((err) => {
throw "ERROR AFTER THEN";
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
备选方案 2:
test1Async(10).then((res) => {
return test2Async(22)
.catch((err) => {
throw "ERROR BEFORE THEN";
})
.then((res) => {
return test3Async(100);
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
每个函数的行为如下,如果数字为<0
,则test1失败如果数字为 > 10
,则 test2 失败如果 number 不是 100
,则 test3 失败.在这种情况下 test2 只是失败了。
我尝试运行并使 test2Async 失败,然后 BEFORE 和 AFTER 的行为方式相同,并且没有执行 test3Async。有人可以向我解释将捕获物放在不同地方的主要区别吗?
在每个函数中我 console.log('Running test X')
为了检查它是否被执行。
这个问题的出现是因为我之前发布的帖子 How to turn nested callback into promise? .我认为这是一个不同的问题,值得发布另一个主题。
最佳答案
所以,基本上你是在问这两者有什么区别(其中 p
是从以前的代码创建的 promise ):
return p.then(...).catch(...);
和
return p.catch(...).then(...);
p 解决或拒绝时存在差异,但这些差异是否重要取决于 .then()
或 .catch()
中的代码处理程序会。
p
解析后会发生什么:
在第一个方案中,当 p
解析时,调用 .then()
处理程序。如果该 .then()
处理程序返回一个值或另一个最终解决的 promise ,则 .catch()
处理程序将被跳过。但是,如果 .then()
处理程序抛出或返回最终拒绝的 promise ,则 .catch()
处理程序将执行原始 promise 中的拒绝p
,但也是在 .then()
处理程序中发生的错误。
在第二种方案中,当 p
解析时,调用 .then()
处理程序。如果该 .then()
处理程序抛出或返回最终拒绝的 promise ,则 .catch()
处理程序无法捕获它,因为它在链中位于它之前。
所以,这就是差异 #1。如果 .catch()
处理程序是 AFTER,那么它也可以在 .then()
处理程序内捕获错误。
p
拒绝时会发生什么:
现在,在第一个方案中,如果 promise p
拒绝,则 .then()
处理程序将被跳过并且 .catch()
处理程序将按照您的预期调用。您在 .catch()
处理程序中执行的操作决定了作为最终结果返回的内容。如果您只是从 .catch()
处理程序返回一个值或返回一个最终解决的 promise ,那么 promise 链将切换到已解决状态,因为您“处理”了错误并正常返回。如果您在 .catch()
处理程序中抛出或返回被拒绝的 Promise,则返回的 Promise 将保持被拒绝。
在第二种方案中,如果 promise p
拒绝,则调用 .catch()
处理程序。如果您返回一个正常值或最终从 .catch()
处理程序解决的 promise (因此“处理”错误),则 promise 链切换到已解决状态和 。
处理程序将被调用。.catch()
之后的 then()
这就是区别 #2。如果 .catch()
处理程序是 BEFORE,那么它可以处理错误并允许 .then()
处理程序仍然被调用。
何时使用:
如果您只需要一个 .catch()
处理程序,可以在原始 promise p
或 .then( )
处理程序和来自 p
的拒绝应该跳过 .then()
处理程序。
如果您希望能够捕获原始 promise p
中的错误,并且可能(取决于条件)允许 promise 链继续解析,则使用第二种方案,从而执行 .then()
处理程序。
其他选项
还有另一个选项可以同时使用两个回调,您可以将其传递给 .then()
,如下所示:
p.then(fn1, fn2)
这保证只有 fn1
或 fn2
之一将被调用。如果 p
解析,则 fn1
将被调用。如果 p
拒绝,则将调用 fn2
。 fn1
中的结果没有任何变化可以使 fn2
被调用,反之亦然。因此,如果您想绝对确保只调用两个处理程序中的一个,而不管处理程序本身发生了什么,那么您可以使用 p.then(fn1, fn2)
。
关于javascript - 之前和之后的捕获位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42013104/