छद्म कोड:
$(document).ajaxError(function(e, xhr, options, error) {
xhr.retry()
})
इससे भी बेहतर यह होगा कि किसी तरह का एक्सपोनेंशियल बैक-ऑफ हो
छद्म कोड:
$(document).ajaxError(function(e, xhr, options, error) {
xhr.retry()
})
इससे भी बेहतर यह होगा कि किसी तरह का एक्सपोनेंशियल बैक-ऑफ हो
जवाबों:
कुछ इस तरह:
$.ajax({
url : 'someurl',
type : 'POST',
data : ....,
tryCount : 0,
retryLimit : 3,
success : function(json) {
//do something
},
error : function(xhr, textStatus, errorThrown ) {
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
//try again
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
//handle error
} else {
//handle error
}
}
});
.success
इस ajax अनुरोध को वापस करने वाले फ़ंक्शन को कॉल करने से जुड़ा हुआ है?
tryCount
और retryLimit
अत्यधिक है। केवल 1 चर का उपयोग करने पर विचार करें:this.retryLimit--; if (this.retryLimit) { ... $.ajax(this) ... }
(function runAjax(retries, delay){
delay = delay || 1000;
$.ajax({
type : 'GET',
url : '',
dataType : 'json',
contentType : 'application/json'
})
.fail(function(){
console.log(retries); // prrint retry count
retries > 0 && setTimeout(function(){
runAjax(--retries);
},delay);
})
})(3, 100);
retries
संपत्ति का उपयोग करना होगा$.ajax
// define ajax settings
var ajaxSettings = {
type : 'GET',
url : '',
dataType : 'json',
contentType : 'application/json',
retries : 3 // <-----------------------
};
// run initial ajax
$.ajax(ajaxSettings).fail(onFail)
// on fail, retry by creating a new Ajax deferred
function onFail(){
if( ajaxSettings.retries-- > 0 )
setTimeout(function(){
$.ajax(ajaxSettings).fail(onFail);
}, 1000);
}
$.ajax
(DRY के लिए बेहतर)// enhance the original "$.ajax" with a retry mechanism
$.ajax = (($oldAjax) => {
// on fail, retry by creating a new Ajax deferred
function check(a,b,c){
var shouldRetry = b != 'success' && b != 'parsererror';
if( shouldRetry && --this.retries > 0 )
setTimeout(() => { $.ajax(this) }, this.retryInterval || 100);
}
return settings => $oldAjax(settings).always(check)
})($.ajax);
// now we can use the "retries" property if we need to retry on fail
$.ajax({
type : 'GET',
url : 'http://www.whatever123.gov',
timeout : 2000,
retries : 3, // <-------- Optional
retryInterval : 2000 // <-------- Optional
})
// Problem: "fail" will only be called once, and not for each retry
.fail(()=>{
console.log('failed')
});
एक बिंदु पर विचार करना सुनिश्चित कर रहा है कि$.ajax
दो बार चल रहे समान कोड से बचने के लिए विधि पहले से ही लपेटी नहीं गई थी।
आप इन स्निपेट्स (जैसे-है) को कॉपी करके उन्हें जांचने के लिए कंसोल पर चिपका सकते हैं
मुझे इस कोड के साथ बहुत सी सफलता मिली है (उदाहरण: http://jsfiddle.net/uZSFK/ )
$.ajaxSetup({
timeout: 3000,
retryAfter:7000
});
function func( param ){
$.ajax( 'http://www.example.com/' )
.success( function() {
console.log( 'Ajax request worked' );
})
.error(function() {
console.log( 'Ajax request failed...' );
setTimeout ( function(){ func( param ) }, $.ajaxSetup().retryAfter );
});
}
इनमें से कोई भी उत्तर काम नहीं करता है यदि कोई व्यक्ति .done()
अपने ajax कॉल के बाद कॉल करता है क्योंकि आपके पास भविष्य के कॉल बैक को संलग्न करने के लिए सफलता की विधि नहीं होगी। तो अगर कोई ऐसा करता है:
$.ajax({...someoptions...}).done(mySuccessFunc);
फिर mySuccessFunc
रिट्रीट पर नहीं बुलाया जाएगा। यहाँ मेरा समाधान है, जो यहाँ @jpak के उत्तर से बहुत अधिक उधार लिया गया है । मेरे मामले में जब AWS का एपीआई गेटवे 502 त्रुटि के साथ प्रतिक्रिया करता है तो मैं फिर से प्रयास करना चाहता हूं।
const RETRY_WAIT = [10 * 1000, 5 * 1000, 2 * 1000];
// This is what tells JQuery to retry $.ajax requests
// Ideas for this borrowed from https://stackoverflow.com/a/12446363/491553
$.ajaxPrefilter(function(opts, originalOpts, jqXHR) {
if(opts.retryCount === undefined) {
opts.retryCount = 3;
}
// Our own deferred object to handle done/fail callbacks
let dfd = $.Deferred();
// If the request works, return normally
jqXHR.done(dfd.resolve);
// If the request fails, retry a few times, yet still resolve
jqXHR.fail((xhr, textStatus, errorThrown) => {
console.log("Caught error: " + JSON.stringify(xhr) + ", textStatus: " + textStatus + ", errorThrown: " + errorThrown);
if (xhr && xhr.readyState === 0 && xhr.status === 0 && xhr.statusText === "error") {
// API Gateway gave up. Let's retry.
if (opts.retryCount-- > 0) {
let retryWait = RETRY_WAIT[opts.retryCount];
console.log("Retrying after waiting " + retryWait + " ms...");
setTimeout(() => {
// Retry with a copied originalOpts with retryCount.
let newOpts = $.extend({}, originalOpts, {
retryCount: opts.retryCount
});
$.ajax(newOpts).done(dfd.resolve);
}, retryWait);
} else {
alert("Cannot reach the server. Please check your internet connection and then try again.");
}
} else {
defaultFailFunction(xhr, textStatus, errorThrown); // or you could call dfd.reject if your users call $.ajax().fail()
}
});
// NOW override the jqXHR's promise functions with our deferred
return dfd.promise(jqXHR);
});
यह स्निपेट 2 सेकंड, फिर 5 सेकंड, फिर 10 सेकंड के बाद बैक-ऑफ और फिर से प्रयास करेगा, जिसे आप RETRY_WAIT स्थिरांक को संशोधित करके संपादित कर सकते हैं।
एडब्ल्यूएस समर्थन ने सुझाव दिया कि हम एक रिट्री को जोड़ते हैं, क्योंकि यह हमारे लिए केवल एक बार नीले चंद्रमा में होता है।
यहाँ इसके लिए एक छोटा सा प्लगइन है:
https://github.com/execjosh/jquery-ajax-retry
ऑटो इंक्रीमेंटिंग टाइमआउट इसके लिए एक अच्छा अतिरिक्त होगा।
इसे विश्व स्तर पर उपयोग करने के लिए केवल $ .ajax हस्ताक्षर के साथ अपना स्वयं का फ़ंक्शन बनाएं, वहां पुनर्प्रयास एपि का उपयोग करें और अपने सभी $ .ajax कॉल को अपने नए फ़ंक्शन द्वारा प्रतिस्थापित करें।
इसके अलावा, आप सीधे $ .ajax की जगह ले सकते हैं, लेकिन आप बिना रिट्रीट के xhr कॉल नहीं कर पाएंगे।
यहाँ वह विधि है जो पुस्तकालयों के अतुल्यकालिक लोडिंग के लिए मेरे लिए काम करती है:
var jqOnError = function(xhr, textStatus, errorThrown ) {
if (typeof this.tryCount !== "number") {
this.tryCount = 1;
}
if (textStatus === 'timeout') {
if (this.tryCount < 3) { /* hardcoded number */
this.tryCount++;
//try again
$.ajax(this);
return;
}
return;
}
if (xhr.status === 500) {
//handle error
} else {
//handle error
}
};
jQuery.loadScript = function (name, url, callback) {
if(jQuery[name]){
callback;
} else {
jQuery.ajax({
name: name,
url: url,
dataType: 'script',
success: callback,
async: true,
timeout: 5000, /* hardcoded number (5 sec) */
error : jqOnError
});
}
}
फिर बस .load_script
अपने ऐप से कॉल करें और अपनी सफलता के कॉलबैक को घोंसला दें:
$.loadScript('maps', '//maps.google.com/maps/api/js?v=3.23&libraries=geometry&libraries=places&language=&hl=®ion=', function(){
initialize_map();
loadListeners();
});
डेमो यूजर्स का जवाब Zepto के साथ काम नहीं करता है, क्योंकि यह एरर फंक्शन में विंडो की ओर इशारा करता है। (और 'इस' का उपयोग करने का यह तरीका पर्याप्त सुरक्षित नहीं है क्योंकि आप नहीं जानते हैं कि वे अजाक्स को कैसे लागू करते हैं या इसकी कोई आवश्यकता नहीं है)।
ज़ेप्टो के लिए, शायद आप नीचे की कोशिश कर सकते हैं, अब तक यह मेरे लिए अच्छा काम करता है:
var AjaxRetry = function(retryLimit) {
this.retryLimit = typeof retryLimit === 'number' ? retryLimit : 0;
this.tryCount = 0;
this.params = null;
};
AjaxRetry.prototype.request = function(params, errorCallback) {
this.tryCount = 0;
var self = this;
params.error = function(xhr, textStatus, error) {
if (textStatus === 'timeout') {
self.tryCount ++;
if (self.tryCount <= self.retryLimit) {
$.ajax(self.params)
return;
}
}
errorCallback && errorCallback(xhr, textStatus, error);
};
this.params = params;
$.ajax(this.params);
};
//send an ajax request
new AjaxRetry(2).request(params, function(){});
निश्चित अनुरोध करने के लिए निर्माणकर्ता का उपयोग करें।
आपका कोड लगभग पूर्ण है :)
const counter = 0;
$(document).ajaxSuccess(function ( event, xhr, settings ) {
counter = 0;
}).ajaxError(function ( event, jqxhr, settings, thrownError ) {
if (counter === 0 /*any thing else you want to check ie && jqxhr.status === 401*/) {
++counter;
$.ajax(settings);
}
});
tries
, और असफल होने पर आप अपने फ़ंक्शन को कॉल कर सकते हैंtries+1
।tries==3
या किसी अन्य नंबर पर निष्पादन रोकें ।