JavaScript Promise:拒绝处理程序与捕获

wal*_*lop 3 javascript node.js promise

我遇到过多个应用程序,其中使用 catch 优于拒绝处理程序。例如:偏好

new Promise.then(resolveHandler).catch()
Run Code Online (Sandbox Code Playgroud)

代替

new Promise().then(resolveHandler, rejectHandler).catch()
Run Code Online (Sandbox Code Playgroud)

这有什么特别的原因吗??

我发现

new Promise().then(resolveHandler, rejectHandler).catch()
Run Code Online (Sandbox Code Playgroud)

更有用,因为

  1. 我可以使用 rejectHandler 来解决调用 Promise.reject 的设计/预期错误场景。
  2. 我可以使用 catch 块来解决发生的未知/意外编程/运行时错误。

有人知道为什么不经常使用拒绝处理程序的任何特殊原因吗?

PS 我知道 ES6 中有更新的替代品,但我只是想知道这一点。

更新:我知道 rejectHandler 和 catch 是如何工作的。问题是为什么我看到更多的人只使用 catch 而不使用 rejectHandler 和 catch?这是最佳实践还是有一些优势?

更新(在此处添加答案):找到了我正在寻找的第一手答案。原因不仅仅是因为拒绝中的错误是由 catch 处理的,主要是因为链接。当我们链接 promise.then.then.then.then 时,有一个解决方案,拒绝模式证明链接它有点棘手,因为您不想实现拒绝处理程序只是为了将拒绝数据向上转发。仅使用 promise/then/catch 和 resolve/return/throw 被证明在链接 N 个 thenable 时非常有用。@Bob-Fanger(接受的答案)也解决了部分问题。例如:

getData(id) {
        return service.getData().then(dataList => {
            const data = dataList.find(data => {
                return data.id === id;
            });
            if (!data) {
                // If I use Promise.reject here and use a reject handler in the parent then the parent might just be using the handler to route the error upwards in the chain
              //If I use Promise.reject here and parent doesn't use reject handler then it goes to catch which can be just achieved using throw.
                throw {
                    code: 404,
                    message: 'Data not present for this ID'
                };
            }
            return configuration;
        });
    }


//somewhere up the chain
....getConfiguration()
            .then(() => {
                //successful promise execution
            })
            .catch(err => {
                if (err.code) {
                    // checked exception
                    send(err);
                } else {
                    //unchecked exception
                    send({
                        code: 500,
                        message: `Internal Server error: ${err}`
                    });
                }
            });
Run Code Online (Sandbox Code Playgroud)

仅使用这些我需要担心的是 promise/then/catch 以及链中任何位置的 resolve/return/throw。

Ada*_*dam 5

两者都不比另一个更有用。当抛出错误或拒绝承诺时,会调用被拒绝的处理程序和 catch 回调。

没有“最佳实践”可以使用一种而不是另一种。您可能会看到代码使用一种或另一种,但它的使用将基于代码需要实现的目标。程序员可能希望在链中的不同时间捕获错误并以不同方式处理在不同时间抛出的错误。

希望以下内容有助于解释我的意思:

somePromise
  .then(
      function() { /* code when somePromise has resolved */ },
      function() { 
        /* code when somePromise has thrown or has been rejected. 
        An error thrown in the resolvedHandler 
        will NOT be handled by this callback */ }
   );

somePromise
  .then(
      function() { /* code when somePromise has resolved */ }
   )
   .catch(
      function() { 
        /* code when somePromise has thrown or has been rejected OR 
        when whatever has occurred in the .then 
        chained to somePromise has thrown or 
        the promise returned from it has been rejected */ }
   );
Run Code Online (Sandbox Code Playgroud)

请注意,在第一个代码段中,如果解析的处理程序抛出,则没有catch可以捕获错误的拒绝处理程序(或回调)。在已解析的回调中抛出的错误不会被指定为第二个参数的rejectedHandler 捕获.then


Bob*_*ger 5

不同之处在于,如果resolveHandler 内部发生错误,则rejectHandler 不会处理它,它只处理原始promise 中的拒绝。

rejectHandler 与 catch 结合使用并不多,因为大多数时候我们只关心出了什么问题。
仅创建一个错误处理程序使代码更易于推理。

如果链中的特定承诺应该以不同的方式处理,这可能是使用拒绝处理程序的原因,但catch().then().catch()在这种情况下我可能会写一个。

  • 有趣的解释。另外关于你的观点,“rejectHandler 并没有与 catch 结合使用那么多,因为大多数时候我们只关心出了什么问题。”,确实,我们只考虑出了什么问题,尽管我随着时间的推移已经意识到它最好考虑一下这是预期的错误还是意外的错误 (2认同)