【问题标题】:Skip $.ajax().fail() when global error handler defined定义全局错误处理程序时跳过 $.ajax().fail()
【发布时间】:2018-05-01 03:38:32
【问题描述】:

我正在为状态代码 500 定义一个全局 jQuery 错误处理程序(当重试用尽时,带有一些消息的重试机制)。我想覆盖任何可能已添加到$.ajax 请求中的.fail() 承诺。我的代码如下:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script type="text/javascript">

            function call() {

                $.ajax({
                  url: '/rest/api/v1/some_errorneous_parth',
                  retryCount:3,
                  method: 'GET'
                }).done(function(data){
                    console.log(data);
                }).fail(function() {
                    console.log("should not print");
                });
            }

            $(document).ready(function () {
                $.ajaxSetup({
                    retryCount: 3,
                    error: function retry(response) {
                        if(response.statuscode === 500) {
                            if(--this.retryCount){
                                $.ajax(this);
                            }
                            else {
                                console.log("sorry, i've 'tried everything");
                            }
                        }
                    }
                });
            });
        </script>
    </head>
    <body>
        <input type="button" onclick="call()" value="submit"/>
    </body>
</html> 

如果服务器返回 500 直到重试计数用完,我希望不打印 should not print

【问题讨论】:

  • fail() 未添加到 ajax 请求中。它正在从 ajax 调用返回的 deferred 中调用 fail 方法。
  • 那么我能否以某种方式更改延迟返回的状态,以便不调用失败。
  • 承诺/延期只解决/拒绝一次。一旦他们这样做了,据我所知,他们的状态不能被翻转。

标签: jquery ajax promise


【解决方案1】:

一些观察...

jQuery 文档提到了.ajaxSetup()

...我们强烈建议不要使用此 API。

文档还说:

使用任何函数的所有后续 Ajax 调用都将使用新设置,除非被各个调用覆盖,直到下一次调用 $.ajaxSetup()。

因此,您期望 $.ajax 请求中的选项被 ajaxSetup 中建立的相应选项覆盖是从后到前的。覆盖则相反。

在任何情况下,.done().fail() 选项都不遵守“被单个调用覆盖”规则。在 ajaxSetup 中建立的失败回调和在单个调用中建立的失败回调将(在错误时)都触发 - 按该顺序。文档没有提供任何警告。

retryCount 等任意选项将被忽略。

重试需要通过其他方式进行安排 - 参见例如Promise Retry Design Patterns

【讨论】:

  • 这一切都很好,除非你有一个遗留的、非系统的代码库,其中有一个全局处理程序$.ajaxSetup 添加了一个授权标头。然后,使用$.ajax() 执行所有其他调用。其实我的真实案例不是重试,而是JWT刷新,过期的时候。因此,当401 被抛出并且后续JWT 刷新成功$.ajaxSetup({ error: when 401})
  • 在这种情况下,我能想到的唯一解决方法是加载第二个 jQuery 副本,其中没有调用 jQuery.ajaxSetup()jQuery.noConflict() 将允许两个副本共存。在您控制的代码中,您可以选择调用原始$.ajax() 或第二个副本,例如$$.ajax()
猜你喜欢
  • 1970-01-01
  • 2013-03-06
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2013-01-04
相关资源
最近更新 更多