【问题标题】:How can I improve this REST request promise code?如何改进此 REST 请求承诺代码?
【发布时间】:2017-08-15 23:55:01
【问题描述】:

我正在尝试在一些检索 REST 资源的代码中改进 Promise 的使用。我有许多 REST 调用使它们执行相同的操作序列:

  1. 如果之前没有获取过配置资源,则从服务器获取配置资源
  2. 分派一个 Flux 动作来指示请求的开始
  3. 发送对实际资源的请求
  4. 解析响应中的 JSON
  5. 使用已解析的数据发送指示成功的通量操作。

我目前用于执行此操作的代码如下。

getThingsFromServer() {
    return getConfigIfNeeded().then(() => {
        dispatchStartOfRequestAction();
        return window.fetch(`${store.baseURL}/resource`)
                     .then((response) => {
                         if(response.ok) {
                             return response.json();
                         } else {
                             return Promise.reject(new Error(`${response.status} ${response.statusText}`));
                         }
                     }, (error) => {
                         return Promise.reject(new Error(`Network error: ${error.message}`));
                     })
                     .then((data) => {
                         dispatchSuccessAction(data);
                     }, (error) => {
                         return Promise.reject(new Error(`JSON parse error: ${error.message}`));
                     })
                     .catch((error) => {
                         dispatchFailureAction(error)
                     });
    });
}

我希望能够单独处理许多错误情况,之后我想调度失败操作(在 catch() 中完成)。

目前,如果单个then() 错误处理程序之一被调用,则在最终调用catch() 之前,还会调用每个后续的then() 错误处理程序。我只想要一个单独的处理程序并调用 catch。

我可以放弃单独处理每个错误并在其末尾使用单个 catch,但各种来源都支持和诋毁在承诺链末端以相同方式处理所有这些不同错误的做法。是否有超出个人意见的“正确”答案?

【问题讨论】:

  • 这个问题可能更适合codereview.stackexchange.com,似乎与 SO 无关
  • 您还想对来自getConfigIfNeeded 的错误进行处理吗?还是从不拒绝?

标签: javascript asynchronous promise


【解决方案1】:

如果单个then() 错误处理程序之一被调用,则每个后续then() 错误处理程序也会被调用

是的,如果你从那个处理程序抛出(或返回一个被拒绝的承诺),承诺将被拒绝,随后的错误处理程序将被调用。真的没有办法解决这个问题。到differentiate the errors,你将have to nest(另见here)。

在你的情况下,你会想要使用

dispatchStartOfRequestAction();
return fetch(`${store.baseURL}/resource`)
.then(response => {
    if (response.ok) {
        return response.json()
        .catch(error => {
            throw new Error(`JSON parse error: ${error.message}`);
        });
    } else {
        throw new Error(`${response.status} ${response.statusText}`);
    }
}, error => {
    throw new Error(`Network error: ${error.message}`);
})
.then(dispatchSuccessAction, dispatchFailureAction);

【讨论】:

  • 我喜欢关于您链接到的承诺的“最多两个级别”的解决方案,我认为这是我最接近清除代码的方法。我现在也突然意识到我需要一个专门的错误处理程序......
猜你喜欢
  • 2015-01-06
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2019-08-29
  • 2016-01-08
  • 2015-04-03
相关资源
最近更新 更多