关于javascript:在完成后转义承诺链

Escaping the promise chain when it's completed

本问题已经有最佳答案,请猛点这里访问。

在开始我的应用程序之前,我想使用Promise链来加载一些数据。 所以,我会有类似的东西:

1
2
3
4
5
6
7
fetch('path/to/data.json')
  .then((response) => response.json())
  .then((data) => {
    console.log(`Hey cool, we're done w/ the promise chain here`);
    startApp(data);
  })
  .catch((error) => console.error(`Error in promise chain: ${error}`));

它确实有效 - 但是通过这种设置,我的startApp函数(或任何后续函数)中的任何错误都在Promise链中处理,这似乎是错误的。

我发现的Promise示例通常以链的最后then()中的控制台日志结束,因此它们对此并不十分有益。

  • 我的设置方式实际上很好吗?
  • 如果没有,我怎么能等到promise链的末尾调用startApp函数而不在链中呢?


你将永远处于承诺链中。但是,您可以轻松地分离逻辑以处理fetch的错误和您的数据消耗App,如下所示:

1
2
3
4
fetch('path/to/data.json')
  .then(response => response.json())
  .then(startApp, handleFetchError)
  .catch(error => console.error(`Error from startApp or handleFetchError: ${error}`));

根据问题中观察到的效果,Promise实现在try/catch块中调用.then处理程序。如果捕获到错误,则then返回的承诺将因同样的原因而被拒绝。

要单独报告应用程序错误,您可以在应用程序周围放置自己的try/catch块并显式处理错误报告。如果顶级then处理程序返回而不重新抛出错误,则不会调用以下catch处理程序。

例如。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fetch('path/to/data.json')
  .then((response) => response.json())
  .then((data) => {
    console.log(`Hey cool, we're done w/ the promise chain here`);
    try {
          startApp(data);
    }
    catch( err) {
      console.log("An application error occurred:");
      console.error( err);
    }
    // returning without re-throwing the error
  })
 .catch((error) => console.error(`Error in promise chain: ${error}`));

我还看到用于在promise链外抛出错误的计时器调用,以防止它们被作为promise错误使用。不确定堆栈跟踪是否足够,但至少它确定发生了应用程序错误:

例如。

1
2
3
4
5
6
7
8
9
10
11
12
fetch('path/to/data.json')
  .then((response) => response.json())
  .then((data) => {
    console.log(`Hey cool, we're done w/ the promise chain here`);
    try {
      startApp(data);
    }
    catch( err) {
        setTimeout( function () { throw err}, 0);
    }
})
.catch((error) => console.error(`Error in promise chain: ${error}`));

另一种方法是使用计时器启动应用程序,因此它不会在promise链中执行以启动:-)

1
setTimeout(startApp, 0, data);