2016-08-19 78 views
0

我使用jQuery與jQuery,因爲我們知道$.ajax返回承諾ajaxPromise。我的要求是:只有當所有的Ajax調用重試失敗時,ajaxPromise捕獲失敗(我想處理ajax承諾回調函數內的錯誤)。jQuery 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) { 
     $.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回調?還是有其他的選擇可以做到這一點?

+0

你知道如何扭曲的範圍界定在JavaScript的?我不確定,但我相信在嵌套的ajax調用中,您的'triedCount'變量會丟失。也許嘗試傳遞迴調中的變量,然後在ajax調用中作爲選項? –

+0

您是否預先知道返回哪個標題?如果是的話,你可以使用statuCode回調。 –

+0

@MridulKashyap'triedCount'變量沒有作用域問題:) – coderz

回答

1
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); 
     } 
    } 
    }); 
} 

在您的代碼中,如果發生錯誤,則調用ajax函數。但這並不意味着之前的ajax調用沒有完成。第一個ajax調用完成併發送返回值(失敗)。您

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

運行,你會得到「所有重試失敗...」登錄到控制檯。 如果你想達到你想達到的目標,你必須攔截前面的結果並阻止它被返回。相反,檢查3次嘗試是否已完成,然後返回值。但我不知道該怎麼做。

編輯:經過長時間的研究,我發現這是不可能的。你應該放棄嘗試做這樣的事情......只是在開玩笑!檢查這個代碼,我相信這正是你想要的東西:

// 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); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

編輯:錯誤拋出從失敗的Ajax調用將在ajaxPromise回調xhr參數可用。

+1

我仍然在尋找一種方式順便說一句。將更新,如果我找到了什麼。 –

+0

也許'不同','然後'有幫助嗎? – coderz

+0

如何更新答案不同於http://stackoverflow.com/a/39031614/?在'.fail()'鏈接到'ajaxPromise'的'this'和'xhr'是什麼? – guest271314

1

您可以使用$.Deferred(),.rejectWith();以$.Deferred()beforeStartajaxOptions作爲參數傳遞調用遞歸函數;如果this.triedCount不低於this.retryLimit少,回報拒絕延期的對象與this設置爲當前AJAX選項,xhr作爲參數傳遞給.fail()鏈接到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 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> 
 
</script>