jQuery ajax - 仅在所有重试失败时触发失败回调函数

时间:2016-08-19 04:31:02

标签: javascript jquery ajax

我在jQuery中使用ajax,我们知道$.ajax会返回一个promise ajaxPromise。我的要求是:只有当所有ajax调用重试失败时,ajaxPromise才能捕获失败(我想在ajax promise回调函数中处理错误)。

我尝试了以下代码:

function ajax(data) {
  return $.ajax({
    url: "...",
    data: data,
    triedCount: 0,
    retryLimit: 3,
    error: function(xhr, textStatus, errorThrown ) {
      console.log("error: " + this.triedCount);
      this.triedCount++;
      if (this.triedCount < this.retryLimit) {
        $.ajax(this);
      }
    }
  });
}

var ajaxPromise = ajax({"id": "123"});
ajaxPromise.fail(function(xhr) {
  console.log("All retries failed...");
  // all retries failed, handle error
});

输出我想要的是:

error: 0
error: 1
error: 2
All retries failed...

实际上输出是:

error: 0
All retries failed...
error: 1
error: 2

看起来第一次调用失败后会立即触发fail回调,而我希望在所有重试失败后触发fail回调。

有没有办法只有当所有重试失败然后触发ajaxPromise.fail回调?或者还有其他选择可以做到吗?

2 个答案:

答案 0 :(得分:1)

var g = $('#<%=lblStatus.ClientID%>').html();
在你的代码中

,如果发生错误,你正在调用ajax函数。但这并不意味着之前的ajax调用没有完成。第一个ajax调用完成并发送返回值(失败)。你的

function ajax(data) {
  return $.ajax({
    url: "...",
    data: data,
    triedCount: 0,
    retryLimit: 3,
    error: function(xhr, textStatus, errorThrown ) {
      console.log("error: " + this.triedCount);
      this.triedCount++;
      if (this.triedCount < this.retryLimit) {
        console.log(this);
        $.ajax(this);
      }
    }
  });
}

运行,并且您将获得“所有重试失败...”登录到控制台。 如果你想实现你想要实现的目标,你必须拦截以前的结果并防止它被返回。相反,检查3次尝试是否已完成,然后返回该值。但我不知道该怎么做。

编辑 :经过长时间的研究,我发现这是不可能的。你应该放弃尝试做这样的事情......开个玩笑!检查这段代码,我相信这正是你想要的:

ajaxPromise.fail(function(xhr) {
 console.log("All retries failed...");
  // all retries failed, handle error
});
// Code goes here

function ajax(data) {
  var dfd = $.Deferred();
  $.ajax({
    url: "...",
    data: data,
    triedCount: 0,
    retryLimit: 3,
    success: function(){
      dfd.resolve("success");
    },
    error: function(xhr, textStatus, errorThrown ) {
      console.log("error: " + this.triedCount);
      this.triedCount++;
      if (this.triedCount < this.retryLimit) {
        $.ajax(this);
      }
      else{
        dfd.reject(xhr);
      }
    }
  });
  return dfd.promise();
}
var ajaxPromise = ajax({"id": "123"});
ajaxPromise.fail(function(xhr) {
  console.log("All retries failed...");
  // all retries failed, handle error
  console.log(xhr.responseText);
});

编辑:失败的ajax调用引发的错误将在<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>回调的xhr参数中提供。

答案 1 :(得分:1)

您可以使用$.Deferred().rejectWith();使用beforeStart $.Deferred()调用递归函数,并将ajaxOptions作为参数传递;如果this.triedCount不小于this.retryLimit,则返回被拒绝的延迟对象,其中this设置为当前ajax选项,xhr作为参数传递给.fail()链接到{{ 1}}

ajaxPromise
function ajax(data) {
  var ajaxOptions = {
    url: "...",
    data: data,
    triedCount: 0,
    retryLimit: 3
  };
  return new $.Deferred(function(dfd) {
    function request(opts) {
      $.ajax(opts)
        .fail(function(xhr, textStatus, errorThrown) {
          console.log("error: " + this.triedCount);
          this.triedCount++;
          if (this.triedCount < this.retryLimit) {
            return request(this)
          } else {
            dfd.rejectWith(this, [xhr])
          }
        })
    }
    request(ajaxOptions)
  })
}

var ajaxPromise = ajax({
  "id": "123"
});
ajaxPromise.fail(function(xhr) {
  console.log("All retries failed...", xhr);
  // all retries failed, handle error
});