【问题标题】:Is it possible to combine multiple identical catch blocks?是否可以组合多个相同的 catch 块?
【发布时间】:2018-07-24 12:06:28
【问题描述】:

我想知道在 es2015 中使用 Promise 链时是否可以将多个相同的 catch 块重构为单个 catch 块。

查看以下承诺链(不管它做什么):

replace(replaceOptions(dirPath + '/' + jsName))
         .then((changes) => {
             fileModifiedPrint(changes);
             removeDocumentation(jsName, dirPath, dirName);
             replace(replaceHTMLID(dirPath + '/' + jsName))
                .then((changes) => {

                })
                .catch((err) => {
                    fileErrorPrint(jsName, dirPath, err, "write"); return;
                })
         })
         .catch((err) => {
             fileErrorPrint(jsName, dirPath, err, "write"); return;
         })

我可以将这两个 catch 块合二为一吗?

【问题讨论】:

标签: javascript syntax ecmascript-6 promise


【解决方案1】:

有点。

当您调用.catch((err) => { /*error catching*/ }) 时,您指定了一个在发生错误时将调用的回调函数。因为您使用相同的代码来捕获错误,所以您可以创建一个函数并将其传递给 catch:

const errorCallback = function(err) { fileErrorPrint(jsName, dirPath, err, "write"); }

replace(replaceOptions(dirPath + '/' + jsName))
         .then((changes) => {
             fileModifiedPrint(changes);
             removeDocumentation(jsName, dirPath, dirName);
             replace(replaceHTMLID(dirPath + '/' + jsName))
                .then((changes) => {

                })
                .catch(errorCallback);
         })
         .catch(errorCallback);

【讨论】:

  • 我认为这不是 OP 所要求的。他们特别要求一个“单一的捕获块”。这仍然有两个 catch 块。
  • 是的,但它更简洁,而且你不必写两次相同的代码
  • 当然,它共享一个通用的实现。这不是问题所要问的。
【解决方案2】:

是否可以组合多个相同的 catch 块?

是的,如果你通过从 .then() 处理程序中返回内部承诺来链接你的承诺,然后让拒绝传播冒泡到单个 .catch() 块:

replace(replaceOptions(dirPath + '/' + jsName)).then((changes) => {
    fileModifiedPrint(changes);
    removeDocumentation(jsName, dirPath, dirName);

    // return this promise to chain it to the parent promise
    return replace(replaceHTMLID(dirPath + '/' + jsName)).then((changes) => {
        // do whatever you want here
    });
}).catch((err) => {
    // this will catch any rejection anywhere in the promise chain
    // that wasn't already caught by someone
    fileErrorPrint(jsName, dirPath, err, "write");
});

当您链接承诺时,被拒绝的承诺将传播回链中它遇到的链中的第一个 .catch() 处理程序。如果在顶层之前没有.catch() 处理程序,那么它将一直到.catch()。这使您可以在本地处理拒绝并将其从链的其余部分“隐藏”起来,或者通过让它向上传播来拒绝整个链。您可以根据最适合您特定情况的逻辑来实施任何一种逻辑。


仅供参考,您也可以像这样在内部 replace() 上取消嵌套 .then()

replace(replaceOptions(dirPath + '/' + jsName)).then((changes) => {
    fileModifiedPrint(changes);
    removeDocumentation(jsName, dirPath, dirName);

    // return this promise to chain it to the parent promise
    return replace(replaceHTMLID(dirPath + '/' + jsName));
}).then((changes) => {
    // results of the second `replace()` call.
    // do whatever you want here
}).catch((err) => {
    // this will catch any rejection anywhere in the promise chain
    // that wasn't already caught by someone
    fileErrorPrint(jsName, dirPath, err, "write");
});

【讨论】:

  • 您可能还想取消嵌套.then((changes) => {…})
  • @Bergi - 添加了该选项。
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多