更好的$ .ajax()。always()(又名完整)

时间:2013-11-07 16:07:32

标签: ajax jquery

我经常发现自己整合jQuery ajax错误和成功结果类似于以下内容:

$.ajax(
  success: function (response, statusText, xhr) {
    handleResponse(true, xhr, statusText, response, callback);
  },
  error: function (xhr, statusText, response) {
    handleResponse(false, xhr, statusText, response, callback);
  });

这通常是因为无论结果如何都需要处理状态更改,但是依赖于它 - 显示此状态更改仅被调用一次就更清楚了。此外,我经常根据特定的响应内容(例如JSON结果中包含的错误)重新分配对错误处理的某些“成功”响应。我也可以从某些类型的错误中整合成功类型的操作。当这些问题相互影响时,它特别提高了整合的清晰度。

我的主要问题是,是否有更好的方法来处理此错误/成功整合?

一个相关的问题是,是否有一些原因jQuery作者似乎故意使这种使用不可访问,例如通过更改成功/错误回调之间的参数顺序,以及不提供对isSuccess的访问权限jqXhr结果的内部结果?

编辑:我知道complete选项(类似于我在标题中提到的always()延迟)。但是,它不提供对成功/错误HTTP状态代码汇总的访问(上面提到的jQuery内部isSuccess),也不会在成功时反序列化JSON。

编辑2:我刚刚发现了可用于测试xhr成功状态的优秀jqXHR.isResolved(),它只会对响应进行手动反序列化。 不幸的是它被列为已弃用,尽管jQuery仍然在内部使用它。

编辑3:来自deferred原型的jqXHR.state()似乎在.always()检查时给出了已完成请求的成功/失败状态。它看起来有点冒险,就像在处理事件时没有按照设计顺序保证这个状态的值。所以也许可能会有变化。此外,以这种方式使用.always()仍然允许我手动反序列化/解释接收的数据。


也许你觉得我因为想要这样做而疯狂。也许你是对的;你是法官。我现在备份的例子是我正在尝试为我的ajax调用添加透明的身份验证重试队列:

    this.exec = function (callback, parameters) {
        queue.add({
            url: settings.url,
            type: settings.post ? 'POST' : 'GET',
            data: parameters && parseInt(parameters) == parameters ? { id: parameters } : parameters,
            success: function (response, statusText, xhr) {
                handleResponse(true, xhr, statusText, response, callback);
            },
            error: function (xhr, statusText, response) {
                handleResponse(false, xhr, statusText, response, callback);
            }
        });
    }
    function handleResponse(success, xhr, statusText, response, callback) {
        if (settings.authRetry && xhr.status == 401) {
            authRetryQueue.notify(xhr);
        }
        else {
            queue.remove(xhr);
            if (callback) {
                if (success) {
                    if (xhr.method == 'GET' || response.StatusText == null || response.StatusText == 'success')
                        callback(true, settings.Model ? new settings.Model(response) : response);
                    else callback(false, response.StatusText);
                }
                else {
                    callback(false, response);
                }
            }
        }
    }

0 个答案:

没有答案