成功之后ajax重试没有.done

我正在向php文件发出请求。 响应在.done(function(msg){})中处理; 和.fail这很好用。 但有时请求会出错。 我为此重试了一次。 重试也有效。 但是如果第一次失败并且在de 2或3中成功尝试我的request.done不会触发(在firebug中我可以看到它是成功的)

我的请求:

var request = $.ajax({ url: "wcf.php", type: "POST", dataType: "xml", async: false, timeout: 5000, tryCount: 0, retryLimit: 3, data: { barcode: value, curPrxID: currentPrxID, timestamp: (new Date).getTime()}, error: function (xhr, ajaxOptions, thrownError) { if (xhr.status == 500) { alert('Server error'); } this.tryCount++; if (this.tryCount < this.retryLimit) { $.ajax(this); //return; } } }) ; 

这是.done并失败:

 request.done(function(msg) { $(msg).find("Response").each(function() { // my code here }); }); request.fail(function(jqXHR, textStatus, errorThrown) { $("#message").html(errorThrown); }); 

.done().fail()方法是Deferred Object的一部分,它在$.ajax()返回的jqXHR对象中实现。 您向其注册的回调不是$.ajax()选项的一部分,因此您无法将它们传递给另一个$.ajax() 。 在您的代码中,您只订阅父$.ajax() Deferred Object回调。 要实现所需的结果,应将整个操作包装在另一个Deferred Object中,并使用.resolveWith() / .rejectWith()方法传递正确的上下文。 此外,您还需要记住, Deferred Object可以将其状态更改为已解决或仅被拒绝一次(换句话说,如果失败则无法在以后成功)。 所以最终的代码可能如下所示:

 var request = $.Deferred(function(deferred) { $.ajax({ url: 'wcf.php', type: 'POST', dataType: 'xml', async: false, timeout: 5000, tryCount: 0, retryLimit: 3, data: { barcode: value, curPrxID: currentPrxID, timestamp: (new Date).getTime()}, error: function (xhr, ajaxOptions, thrownError) { if (xhr.status == 500) { alert('Server error'); } this.tryCount++; if (this.tryCount < this.retryLimit) { $.ajax(this).done(function(data, textStatus, jqXHR) { deferred.resolveWith(this, [data, textStatus, jqXHR]); }).fail(function(jqXHR, textStatus, errorThrown) { if (this.tryCount >= this.retryLimit) { deferred.rejectWith(this, [jqXHR, textStatus, errorThrown]); } }); } } }).done(function(data, textStatus, jqXHR) { deferred.resolveWith(this, [data, textStatus, jqXHR]); }); }).promise(); request.done(function(msg) { $(msg).find("Response").each(function() { //Success code here }); }); request.fail(function(jqXHR, textStatus, errorThrown) { $("#message").html(errorThrown); });