JQuery AJAX अनुरोध को रद्द / निरस्त कैसे करें?


244

मैंने एक AJAX अनुरोध किया है जिसे हर 5 सेकंड में बनाया जाएगा। लेकिन समस्या AJAX अनुरोध से पहले है यदि पिछला अनुरोध पूरा नहीं हुआ है तो मैंने उस अनुरोध को निरस्त कर दिया है और एक नया अनुरोध किया है।

मेरा कोड कुछ इस तरह है, इस मुद्दे को कैसे हल करें?

$(document).ready(
    var fn = function(){
        $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);


5
आपका प्रश्न कहता है कि अनुरोध हर 5 सेकंड में होना चाहिए, लेकिन कोड 500 एमएस = 0.5 एस का उपयोग करता है।
जौन

जवाबों:


355

Jquery ajax मेथड XMLHttpRequest ऑब्जेक्ट देता है । अनुरोध को रद्द करने के लिए आप इस ऑब्जेक्ट का उपयोग कर सकते हैं।

XMLHttpRequest के पास एक गर्भपात विधि है, जो अनुरोध को रद्द कर देती है, लेकिन यदि अनुरोध पहले ही सर्वर पर भेजा जा चुका है, तो सर्वर अनुरोध को रद्द कर देगा, भले ही हम अनुरोध को रद्द कर दें, लेकिन ग्राहक प्रतिक्रिया का इंतजार नहीं करेगा / संभाल सकेगा।

XHR वस्तु भी एक शामिल readyState जो अनुरोध के राज्य शामिल हैं (नहीं भेजे गए -0, खोला -1, HEADERS_RECEIVED -2, लोड हो रहा है -3 और किया -4)। हम यह जांचने के लिए उपयोग कर सकते हैं कि क्या पिछला अनुरोध पूरा हो गया था।

$(document).ready(
    var xhr;

    var fn = function(){
        if(xhr && xhr.readyState != 4){
            xhr.abort();
        }
        xhr = $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);

60
@romkyns अंतर readystateऊपर और readyStateनीचे की संपत्ति है , चरित्र sको jQuery 1.5 में कैपिटल किया गया है
अरुण पी जॉनी

मैं सोच रहा था कि क्या होगा अगर रेडीस्टेट "LOADING-3" है और हम गर्भपात करते हैं? डेटा सर्वर को भेजा जाता है, और यह संसाधित होता है या नहीं। हम नहीं जानते ...: S
inf3rno

7
Btw, मुझे लगता है कि रेडीस्टेट चेक अनावश्यक है, क्योंकि यह स्थगित है और एक बार इसे हल करने या अस्वीकार करने के बाद यह दूसरों को नहीं चलाएगा। तो if (xhr) xhr.abort();बस ठीक काम करेगा।
Ciantic

2
W3 ने कभी भी readystateइसके प्रलेखन में पूंजीकृत नहीं किया । यह हमेशा पूंजीकृत था readyStateऔर jquery (1.5 से पहले या बाद में) w3 विनिर्देश से सही ढंग से मेल खाता है।
अर्शसॉफ्ट

@ArunPJohny, तो आप इस प्रश्न pls कर सकते हैं stackoverflow.com/questions/49801146/...
कृष्णा Jonnalagadda

6

जब आप किसी सर्वर से अनुरोध करते हैं, तो यह देखने के लिए जांचें कि क्या प्रगति पहले शून्य (या उस डेटा को प्राप्त करना) नहीं है। यदि यह डेटा प्राप्त कर रहा है, तो पिछले अनुरोध को रद्द करें और नया आरंभ करें।

var progress = null

function fn () {    
    if (progress) {
        progress.abort();
    }
    progress = $.ajax('ajax/progress.ftl', {
        success: function(data) {
            //do something
            progress = null;
        }
    });
}

5

मुझे पता है कि यह थोड़ी देर हो सकती है, लेकिन मैं ऐसे ही मुद्दों का अनुभव करता हूं जहां गर्भपात विधि को कॉल करना वास्तव में अनुरोध को रद्द नहीं करता है। इसके बजाय ब्राउज़र अभी भी एक ऐसी प्रतिक्रिया की प्रतीक्षा कर रहा था जिसका वह कभी उपयोग न करे। इस कोड ने उस समस्या को हल कर दिया।

 try {
        xhr.onreadystatechange = null;
        xhr.abort();
} catch (e) {}

1

आपको अनुरोध को रद्द क्यों करना चाहिए?

यदि प्रत्येक अनुरोध में पांच सेकंड से अधिक समय लगता है, तो क्या होगा?

यदि अनुरोध पैरामीटर बदल नहीं रहा है, तो आपको अनुरोध रद्द नहीं करना चाहिए। उदाहरण: - अनुरोध अधिसूचना डेटा को पुनः प्राप्त करने के लिए है। ऐसी स्थितियों में, अच्छा तरीका यह है कि पिछले Ajax अनुरोध को पूरा करने के बाद ही एक नया अनुरोध सेट करें।

$(document).ready(

    var fn = function(){

        $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            },

            complete: function(){setTimeout(fn, 500);}
        });
    };

     var interval = setTimeout(fn, 500);

);

5
यह विचार अच्छा नहीं है। एक नया कॉल शुरू करते समय, आप नहीं चाहते कि पूरा इवेंट पिछली कॉल से निकाल दिया जाए। इस दृष्टिकोण के साथ आपको बहुत ही अजीब परिणाम मिल सकते हैं।
वेबरिग

1

आप jquery-validate.js का उपयोग कर सकते हैं। निम्नलिखित jquery-validate.js से कोड स्निपेट है।

// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()

var pendingRequests = {},
    ajax;
// Use a prefilter if available (1.5+)
if ( $.ajaxPrefilter ) {
    $.ajaxPrefilter(function( settings, _, xhr ) {
        var port = settings.port;
        if ( settings.mode === "abort" ) {
            if ( pendingRequests[port] ) {
                pendingRequests[port].abort();
            }
            pendingRequests[port] = xhr;
        }
    });
} else {
    // Proxy ajax
    ajax = $.ajax;
    $.ajax = function( settings ) {
        var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
            port = ( "port" in settings ? settings : $.ajaxSettings ).port;
        if ( mode === "abort" ) {
            if ( pendingRequests[port] ) {
                pendingRequests[port].abort();
            }
            pendingRequests[port] = ajax.apply(this, arguments);
            return pendingRequests[port];
        }
        return ajax.apply(this, arguments);
    };
}

ताकि आपको केवल अजाक्स अनुरोध करते समय गर्भपात करने के लिए पैरामीटर मोड सेट करने की आवश्यकता हो ।

रेफरी: https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js


0

jQuery: इसे एक प्रारंभिक बिंदु के रूप में - प्रेरणा के रूप में उपयोग करें। मैंने इसे इस तरह हल किया: (यह एक सही समाधान नहीं है, यह सिर्फ पिछले उदाहरण को मिटाता है और WIP कोड है)

var singleAjax = function singleAjax_constructor(url, params) {
    // remember last jQuery's get request
    if (this.lastInstance) {
        this.lastInstance.abort();  // triggers .always() and .fail()
        this.lastInstance = false;
    }

    // how to use Deferred : http://api.jquery.com/category/deferred-object/
    var $def = new $.Deferred();

    // pass the deferrer's request handlers into the get response handlers
    this.lastInstance = $.get(url, params)
        .fail($def.reject)         // triggers .always() and .fail()
        .success($def.resolve);    // triggers .always() and .done()

    // return the deferrer's "control object", the promise object
    return $def.promise();
}


// initiate first call
singleAjax('/ajax.php', {a: 1, b: 2})
    .always(function(a,b,c) {console && console.log(a,b,c);});

// second call kills first one
singleAjax('/ajax.php', {a: 1, b: 2})
    .always(function(a,b,c) {console && console.log(a,b,c);});
    // here you might use .always() .fail() .success() etc.

0

अपने एपीआई को कॉल करने के लिए एक फ़ंक्शन बनाएं। इस फ़ंक्शन के भीतर हम अनुरोध को परिभाषित करते हैं callApiRequest = $.get(...- भले ही यह एक चर की परिभाषा है, अनुरोध को तुरंत कहा जाता है, लेकिन अब हमारे पास अनुरोध को एक चर के रूप में परिभाषित किया गया है। अनुरोध को कॉल करने से पहले, हम जाँचते हैं कि क्या हमारा वेरिएबल परिभाषित है typeof(callApiRequest) != 'undefined'और यह लंबित होने पर भी suggestCategoryRequest.state() == 'pending'- यदि दोनों सत्य हैं, तो हम .abort()अनुरोध करते हैं जो सफलता की कॉलबैक को चलने से रोकेगा।

// We need to wrap the call in a function
callApi = function () {

    //check if request is defined, and status pending
    if (typeof(callApiRequest) != 'undefined'
        && suggestCategoryRequest.state() == 'pending') {

        //abort request
        callApiRequest.abort()

    }

    //define and make request
    callApiRequest = $.get("https://example.com", function (data) {

        data = JSON.parse(data); //optional (for JSON data format)
        //success callback

    });
}

आपका सर्वर / एपीआई अनुरोध को निरस्त करने का समर्थन नहीं कर सकता है (अगर एपीआई ने पहले से ही कुछ कोड निष्पादित किया है?), लेकिन जावास्क्रिप्ट कॉलबैक में आग नहीं लगेगी। यह उपयोगी है, जब उदाहरण के लिए आप किसी उपयोगकर्ता को इनपुट सुझाव प्रदान कर रहे हैं, जैसे हैशटैग इनपुट।

आप त्रुटि कॉलबैक की परिभाषा को जोड़कर इस फ़ंक्शन को आगे बढ़ा सकते हैं - यदि अनुरोध रद्द कर दिया गया था तो क्या होना चाहिए।

इस स्निपेट के लिए सामान्य उपयोग-मामला एक पाठ इनपुट होगा जो keypressघटना पर आग लगाता है । आप (कुछ) अनुरोध भेजने से रोकने के लिए एक टाइमआउट का उपयोग कर सकते हैं, जिसे आपको रद्द करना होगा .abort()


-7

आपको रेडीस्टेट 0. की भी जांच करनी चाहिए क्योंकि जब आप xhr.abort () का उपयोग करते हैं तो यह फंक्शन इस ऑब्जेक्ट में रेडीस्टेट को 0 पर सेट करता है, और आपका चेक हमेशा सही रहेगा - रेडीस्टेट! = 4

$(document).ready(
    var xhr;

    var fn = function(){
        if(xhr && xhr.readyState != 4 && xhr.readyState != 0){
            xhr.abort();
        }
        xhr = $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
); 

2
क्या आपने अरुण के जवाब को कॉपी और पेस्ट किया? क्योंकि दो कोड ब्लॉक होने की संभावना बिल्कुल वैसी ही है, रिक्ति और सभी ...

@ user2700923 उनकी पोस्ट बिल्कुल वैसी नहीं है। उनका कहना है कि हमें रेडीस्टेट 0. के लिए भी जांच करनी चाहिए। हालांकि अरुण के जवाब के लिए टिप्पणी के रूप में यह अधिक उपयुक्त होगा।
स्टीफन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.