为什么使用Promise.finally最终导致未捕获的异常?

克里斯·F

我正在实现一个函数timeout该函数将一个Promise转换为一个Promise,如果未在最短时间内解决该Promise,该Promise将被拒绝。

通过以下实现,uncaught (in promise)timeout在分配的时间之前将promise传递给rejects,我会在Chrome devtools中收到一条消息

function timeout(promise, duration, message) {
    const timeoutPromise = new Promise((_, reject) => {
        const handle = setTimeout(() => {
            reject(new TimeoutError(message ?? "Operation timed out."))
        }, duration)
        promise.finally(() => clearTimeout(handle)) //problem line
    })
    return Promise.race([promise, timeoutPromise])
}

但是,如果将其更改为以下内容,则似乎没有问题。

function timeout(promise, duration, message) {
    const timeoutPromise = new Promise((_, reject) => {
        const handle = setTimeout(() => {
            reject(new TimeoutError(message ?? "Operation timed out."))
        }, duration)
        const clear = () => clearTimeout(handle)
        promise.then(clear).catch(clear)
    })
    return Promise.race([promise, timeoutPromise])
}

我试图了解在第二种情况下调用then&与catch在第一种情况下调用有何不同finally

TJ人群

这是因为finally处理程序不同于thencatch处理程序。如果承诺被拒绝,则finally处理程序无法将拒绝更改为解决方案。finally一个的块try/ catch/finally结构,它的意思是基本上透明的。

这是我在新书中描述的方式(第8章):

在正常情况下,finally处理程序对通过它的实现或拒绝没有影响(就像一个finally块):它返回的任何值(除了被拒绝的thenable之外)都将被忽略。但是,如果它抛出错误或返回拒绝的罐头,则该错误/拒绝会取代通过它的任何实现或拒绝(就像在finally块中抛出一样)。因此,它不能更改实现值-即使返回一个不同的值也是如此-但可以将拒绝原因更改为不同的拒绝原因,可以将实现更改为拒绝,并且可以延迟实现(通过返回最终实现的目标。

或换一种说法:它就像一个finally不能包含return语句(它可能具有throw或可能会调用一个函数或执行一些引发操作的操作,但是它不能返回新值。

这是一个无法将拒绝转化为实现的示例:

Promise.reject(new Error("Failed"))
.finally(() => {
    console.log("finally handler returns null");
    return null;
});
Look in the browser's real console to see the unhandled rejection error.


在您的代码中处理它的另一种方法是代替问题行执行此操作:

promise.catch(() => {}).finally(() => clearTimeout(handle))

要么

promise.catch(() => {}).then(() => clearTimeout(handle))

它将finally(或then)处理程序之前的拒绝转换为实现(仅在此分支上)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么未捕获多父异常?

来自分类Dev

为什么会有未捕获的异常?

来自分类Dev

为什么未捕获此异常?

来自分类Dev

为什么未捕获到异常?

来自分类Dev

为什么try catch块没有捕获promise异常?

来自分类Java

Java 7-> Java 8:AES导致异常:“ BadPaddingException:给定的最终块未正确填充”与BufferedReader和ZipStreams结合使用

来自分类Dev

Angular Promise不会记录未捕获的异常

来自分类Dev

为什么使用 Promise()?

来自分类Java

使用最终成员处理构造函数中捕获的Java异常

来自分类Dev

通过ajax调用使用模式“ MMMM yyyy”更新组件primefaces datepicker,导致“在位置[...]上未捕获的名称”异常

来自分类Dev

在函数中最终使用 Promise 时 JS 未捕获错误

来自分类Dev

为什么std :: future和std :: promise不是最终的?

来自分类Dev

导致中止的未捕获异常

来自分类Dev

使用 Invoke 时未捕获异常

来自分类Dev

在AngularJS中使用回调而不是Promise会导致单元测试中的行为不同。为什么?

来自分类Dev

PHP的最终是为未捕获的异常?

来自分类Dev

为什么新的Promise的reject()会在可怕的“未捕获(承诺)”错误中丢失堆栈跟踪

来自分类Dev

为什么从Bluebird Promise中的异步函数内引发的错误未捕获在.catch()函数中?

来自分类Javascript

为什么我的JS promise捕获错误对象为空?

来自分类Dev

为什么此Node片段无法捕获拒绝的Promise?

来自分类Dev

为什么Promise不会捕获异步操作引发的错误?

来自分类Dev

使用try:捕获异常时,为什么不能返回?

来自分类Dev

为什么要使用特定的异常捕获块

来自分类Dev

为什么VS Code从Promise中的Reject中断处理的异常?

来自分类Dev

为什么隐式使用ToString()不会导致异常?

来自分类Dev

为什么 PHP 在尝试实例化 SoapClient 对象时无法捕获导致的异常?

来自分类Dev

使用 lambda 异步处理异常,未捕获异常

来自分类Dev

为什么会收到未使用的Lambda捕获警告?

来自分类Dev

为什么gulp-livereload导致“未捕获的SyntaxError:意外的令牌<”?

Related 相关文章

  1. 1

    为什么未捕获多父异常?

  2. 2

    为什么会有未捕获的异常?

  3. 3

    为什么未捕获此异常?

  4. 4

    为什么未捕获到异常?

  5. 5

    为什么try catch块没有捕获promise异常?

  6. 6

    Java 7-> Java 8:AES导致异常:“ BadPaddingException:给定的最终块未正确填充”与BufferedReader和ZipStreams结合使用

  7. 7

    Angular Promise不会记录未捕获的异常

  8. 8

    为什么使用 Promise()?

  9. 9

    使用最终成员处理构造函数中捕获的Java异常

  10. 10

    通过ajax调用使用模式“ MMMM yyyy”更新组件primefaces datepicker,导致“在位置[...]上未捕获的名称”异常

  11. 11

    在函数中最终使用 Promise 时 JS 未捕获错误

  12. 12

    为什么std :: future和std :: promise不是最终的?

  13. 13

    导致中止的未捕获异常

  14. 14

    使用 Invoke 时未捕获异常

  15. 15

    在AngularJS中使用回调而不是Promise会导致单元测试中的行为不同。为什么?

  16. 16

    PHP的最终是为未捕获的异常?

  17. 17

    为什么新的Promise的reject()会在可怕的“未捕获(承诺)”错误中丢失堆栈跟踪

  18. 18

    为什么从Bluebird Promise中的异步函数内引发的错误未捕获在.catch()函数中?

  19. 19

    为什么我的JS promise捕获错误对象为空?

  20. 20

    为什么此Node片段无法捕获拒绝的Promise?

  21. 21

    为什么Promise不会捕获异步操作引发的错误?

  22. 22

    使用try:捕获异常时,为什么不能返回?

  23. 23

    为什么要使用特定的异常捕获块

  24. 24

    为什么VS Code从Promise中的Reject中断处理的异常?

  25. 25

    为什么隐式使用ToString()不会导致异常?

  26. 26

    为什么 PHP 在尝试实例化 SoapClient 对象时无法捕获导致的异常?

  27. 27

    使用 lambda 异步处理异常,未捕获异常

  28. 28

    为什么会收到未使用的Lambda捕获警告?

  29. 29

    为什么gulp-livereload导致“未捕获的SyntaxError:意外的令牌<”?

热门标签

归档