使用fetch& amp;处理自定义错误的最简洁方法ES6承诺

时间:2015-11-25 02:19:19

标签: javascript promise ecmascript-6 es6-promise fetch-api

我正在尝试使用fetch& amp;智能地处理来自API的成功/错误响应ES6承诺。

以下是我需要处理响应状态的方法:

fetch()
  .then(response => checkStatus(response))
  .then(parseJSON)                           //will throw for the 204
  .then(data => notify('success', someMsg))
  .catch(error => checkErrorStatus(error))
  .then(parseJSON)
  .then(data => notify('error', dataForMsg)
  .catch(error => notify('error', someGenericErrorMsg)

所以,我正在努力学习如何干净利落地写作。

我现在有一些不太常用的代码,看起来像这样:

checkStatus

但是使用catch两次似乎很奇怪,我还不知道如何处理那个204.

另外,只是为了澄清checkErrorStatusexport function checkStatus(response) { if (response.status >= 200 && response.status < 300) { return response } else { let error = new Error(response.statusText) error.response = response throw error } } function checkErrorStatus(error) { if(error.response.status === 422) { return error.response } else { let error = new Error(response.statusText) error.response = response throw error } } 做类似的事情:

class LexiconsSerializer(serializers.ModelSerializer):
    lexicon_attributes = LexiconAttributesSerializer()
    class Meta:
        model = Lexicons
        fields = '__all__'

有关清理的建议吗?

2 个答案:

答案 0 :(得分:18)

我认为你可以很容易地写出来:

fetch(…).then(response => {
    if (response.ok)
        return response[response.status == 204 ? "text" : "json"]();
    if (response.status == 422)
        return response.json().then(err => { throw err; });
    if (response.status == 406)
        var error = new AuthentificationError(response.statusText); // or whatever
    else
        var error = new Error(response.statusText)
    error.response = response
    throw error;
})

答案 1 :(得分:3)

继Bergi的解决方案之后,您可能会考虑使用相当简单的ResponseHandler()对象来机械化响应的处理;

function ResponseHandler() {
    this.handlers = [];
    this.handlers[0] = function() {}; // a "do nothing" default handler
}
ResponseHandler.prototype.add = function(code, handler) {
    this.handlers[code] = handler;
};
ResponseHandler.prototype.handle = function(response) {
    var h = this.handlers,
        s = response.status,
        series = Math.floor(s / 100) * 100; // 100, 200, 300 etc
    (h[s] || h[series] || h[0])(response); // sniff down the line for a specific/series/default handler, then execute it.
};

使用中:

// create an instance of ResponseHandler() and add some handlers :
var responseHandler = new ResponseHandler();
responseHandler.add(204, function(response) {...}); // specific handler
responseHandler.add(422, function(response) {...}); // specific handler
responseHandler.add(406, function(response) {...}); // specific handler
responseHandler.add(200, function(response) {...}); // 200 series default handler
responseHandler.add(400, function(response) {...}); // 400 series default handler
responseHandler.add(0, function(response) {...}); // your overall default handler

// then :
fetch(…).then(response => { responseHandler.handle(response); });

您将失去Bergi等硬编码解决方案的效率,但可能会从改进的可管理性和可重用性中获益。