函数中使用Promisefinally时JS未捕获错误

问题描述 投票:0回答:1

这是JS代码:

function createPromise() {
  const result = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error('my error'));
    }, 2000);
  });
// uncomment this to get error
//  result.finally(() => {
//     console.log('finally before');
//  });

  return result;
}

function test() {
  createPromise()
    .then(() => {
      console.log('promise then');
    })
    .catch((error) => {
      console.log('promise catch:', error);
    })
    .finally(() => {
      console.log('promise finally');
    });
}

它工作正常,执行后我在控制台中:

承诺捕获:错误:我的错误
最后的承诺

但是取消注释后:

result.finally(() => {
     console.log('finally before');
  });

在控制台中我没有捕获异常:

终于在之前
承诺捕获:错误:我的错误
最后答应
未捕获(承诺)错误:我的错误

为什么会发生这种情况以及如何解释?

javascript promise
1个回答
2
投票

未兑现的承诺

.then
.catch
一样,
.finally
返回一个承诺。但与提供
.catch
处理程序的第二个参数的
.then
onrejection
不同,如果链中的前一个承诺被拒绝,
finally
不会履行它返回的承诺。

因此,没有

result
承诺注释的预期输出是相同的。但此外,
.finally
createPromise
中返回的承诺没有拒绝处理程序。因此出现了未捕获的承诺拒绝错误。

函数

.finally
中的
test
没问题,因为前面的 catch 子句满足了它返回的 Promise,所以
.finally
不会拒绝它返回的 Promise。


更多关于承诺的

finally
方法

  • 通常,

    .finally
    子句将 Promise 链中前一个 Promise 的结果或 Promise 拒绝原因传递到链中的下一个 Promise。

  • 但是,如果

    finally
    处理程序代码在调用时抛出错误或返回被拒绝的 Promise,则链中的下一个 Promise 会因相同的错误或拒绝原因而被拒绝 - 来自链中先前 Promise 的任何数据或拒绝原因都是被有效丢弃。


如何停止

finally
处理程序代码生成未捕获的拒绝错误。

  1. 返回对新 Promise 调用

    finally
    形成的链:

     function createPromise() {
    
         return new Promise((resolve, reject) => {
           setTimeout(() => {
             reject(new Error('my error'));
           }, 2000);
         })
         .finally( () => {
           console.log('finally before');
         });
     }
    

    如果

    finally
    处理程序抛出或返回拒绝的 Promise,则此类抛出值或拒绝原因会拒绝调用
    finally
    时同步返回的 Promise,将其留给
    createPromise
    的调用者处理。

  2. 抑制未捕获拒绝原因的第二种方法是添加虚拟

    catch
    处理程序,尽管这很少使用,并且在大多数情况下不推荐。

     result.finally(() => {
       console.log('finally before');
     })
     .catch( err => err); // avoid unhandled rejection
    

    将通过让

    finally
    返回从未使用过的已履行承诺来处理源自
    catch
    处理程序内部的承诺拒绝。

© www.soinside.com 2019 - 2024. All rights reserved.