如何改进此REST请求承诺代码?

时间:2017-08-15 14:35:54

标签: javascript asynchronous promise

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

  1. 如果以前未获得配置资源,则从服务器获取配置资源
  2. 发出表示请求开始的助焊剂行动
  3. 发送实际资源请求
  4. 在响应中解析JSON
  5. 发送一个指示已解析数据成功的助焊剂操作。
  6. 我目前用来执行此操作的代码如下。

    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()错误处理程序,则在最终调用then()之前也会调用每个后续的catch()错误处理程序。我只想要一个单独的处理程序并调用catch。

    我可以省去单独处理每个错误并在其末尾使用单个catch但是各种来源都支持和诋毁在promise链的末尾以相同方式处理所有这些不同错误的做法。除了个人观点之外,是否有一个“正确”的答案?

1 个答案:

答案 0 :(得分:1)

  

如果调用其中一个then()错误处理程序,则还会调用每个后续then()错误处理程序

是的,如果你从当时的处理程序中抛出(或返回一个被拒绝的promise),那么promise将被拒绝并且后续的错误处理程序将被调用。真的没办法解决这个问题。要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);