javascript - JQuery का उपयोग कर अजाक्स अनुरोधों को छोड़ दें




ajax (12)

JQuery का उपयोग करके, मैं एक अजाक्स अनुरोध को रद्द / निरस्त कैसे कर सकता हूं जिसे मुझे अभी तक प्रतिक्रिया प्राप्त नहीं हुई है?


AJAX अनुरोध वे शुरू किए गए क्रम में पूरा नहीं हो सकते हैं। निरस्त करने के बजाय, आप सबसे हालिया एक को छोड़कर सभी AJAX प्रतिक्रियाओं को अनदेखा करना चुन सकते हैं:

  • काउंटर बनाएं
  • जब आप AJAX अनुरोध शुरू करते हैं तो काउंटर बढ़ाएं
  • अनुरोध के "टिकट" के काउंटर के वर्तमान मूल्य का उपयोग करें
  • सफलता कॉलबैक में काउंटर के साथ टिकट की तुलना करने के लिए तुलना करें कि यह सबसे हालिया अनुरोध है या नहीं

कोड की कठोर रूपरेखा:

var xhrCount = 0;
function sendXHR() {
    // sequence number for the current invocation of function
    var seqNumber = ++xhrCount;
    $.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() {
        // this works because of the way closures work
        if (seqNumber === xhrCount) {
            console.log("Process the response");
        } else {
            console.log("Ignore the response");
        }
    });
}
sendXHR();
sendXHR();
sendXHR();
// AJAX requests complete in any order but only the last 
// one will trigger "Process the response" message

जेएसएफडल पर डेमो


अधिकांश jQuery अजाक्स विधियों में XMLHttpRequest (या समकक्ष) ऑब्जेक्ट लौटाता है, ताकि आप abort() उपयोग कर सकें।

दस्तावेज देखें:

  • निरस्त विधि ( MSDN )। वर्तमान HTTP अनुरोध रद्द करता है।
  • abort() ( MDN )। अगर अनुरोध पहले से ही भेजा गया है, तो यह विधि अनुरोध को रद्द कर देगी।
var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

अद्यतन: jQuery 1.5 के रूप में लौटाया गया ऑब्जेक्ट देशी XMLHttpRequest ऑब्जेक्ट के लिए jqXHR नामक एक रैपर है। यह ऑब्जेक्ट सभी मूल गुणों और विधियों का पर्दाफाश करने के लिए प्रतीत होता है, इसलिए उपरोक्त उदाहरण अभी भी काम करता है। JqXHR ऑब्जेक्ट (jQuery एपीआई दस्तावेज) देखें।

अद्यतन 2: jQuery 3 के रूप में, AJAX विधि अतिरिक्त विधियों (जैसे निरस्त) के बिना एक वादा देता है, इसलिए यह अब काम नहीं करेगा। यहां 3.0 ब्लॉग देखें। इस के आसपास एक तरीका xhr संपत्ति के माध्यम से xhr ऑब्जेक्ट को नियंत्रित करना है। यहां एक कच्चा उदाहरण है:

var xhr = new window.XMLHttpRequest();
var request = $.ajax({
    url : url,
    xhr : function(){
        return xhr;
    }
});
xhr.abort();

आपके द्वारा सरणी में किए गए कॉल को सहेजें, फिर प्रत्येक पर xhr.abort () को कॉल करें।

बड़ी चेतावनी: आप एक अनुरोध निरस्त कर सकते हैं, लेकिन यह केवल ग्राहक पक्ष है। सर्वर पक्ष अभी भी अनुरोध संसाधित कर सकता है। यदि आप सत्र डेटा के साथ PHP या ASP जैसे कुछ का उपयोग कर रहे हैं, तो AJAX समाप्त होने तक सत्र डेटा लॉक हो जाता है। इसलिए, उपयोगकर्ता को वेबसाइट ब्राउज़ करना जारी रखने की अनुमति देने के लिए, आपको session_write_close () को कॉल करना होगा । यह सत्र बचाता है और इसे अनलॉक करता है ताकि अन्य पेज जारी रखने की प्रतीक्षा कर सकें। इसके बिना, लॉक को हटाने के लिए कई पेज इंतजार कर सकते हैं।


इस तरह कुछ करने के लिए हमेशा सबसे अच्छा अभ्यास है।

var $request;
if ($request != null){ 
    $request.abort();
    $request = null;
}

$request = $.ajax({
    type : "POST", //TODO: Must be changed to POST
    url : "yourfile.php",
    data : "data"
    }).done(function(msg) {
        alert(msg);
    });

लेकिन अगर आप यह जांचने के लिए कि क्या एजेक्स अनुरोध शून्य है या नहीं, तो यह एक बेहतर बयान जांचता है।


चूंकि थ्रेड पर कई लोगों ने ध्यान दिया है, सिर्फ क्लाइंट-साइड पर अनुरोध निरस्त कर दिया गया है, सर्वर अभी भी अनुरोध को संसाधित करेगा। यह सर्वर पर अनावश्यक भार बनाता है क्योंकि यह काम कर रहा है जिसे हमने सामने के अंत में सुनना छोड़ दिया है।

जिस समस्या को मैं हल करने की कोशिश कर रहा था (वह अन्य भी साथ चल सकते हैं) यह है कि जब उपयोगकर्ता इनपुट क्षेत्र में जानकारी दर्ज करता है, तो मैं Google इंस्टेंट प्रकार के अनुभव के लिए अनुरोध बंद करना चाहता था।

अनावश्यक अनुरोधों को फायर करने और सामने के अंत की तस्वीर को बनाए रखने से बचने के लिए, मैंने निम्नलिखित किया:

var xhrQueue = [];
var xhrCount = 0;

$('#search_q').keyup(function(){

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

        if (xhrCount === xhrQueue.length) {
            // Fire Your XHR //
        }

    }, 150);

});

यह अनिवार्य रूप से प्रत्येक 150ms (एक चर जो आप अपनी आवश्यकताओं के लिए अनुकूलित कर सकते हैं) एक अनुरोध भेज देंगे। अगर आपको यह समझने में परेशानी हो रही है कि वास्तव में क्या हो रहा है, तो ब्लॉक ब्लॉक से पहले कंसोल पर xhrCount और xhrQueue लॉग करें।


निम्नलिखित कोड एक अजाक्स अनुरोध को शुरू करने के साथ-साथ शुरू करने से भी पता चलता है:

function libAjax(){
  var req;
  function start(){

  req =    $.ajax({
              url: '1.php',
              success: function(data){
                console.log(data)
              }
            });

  }

  function stop(){
    req.abort();
  }

  return {start:start,stop:stop}
}

var obj = libAjax();

 $(".go").click(function(){


  obj.start();


 })



 $(".stop").click(function(){

  obj.stop();


 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
   <input type="button" class="stop" value="STOP!" >

बस एक्सएचआर कॉल करें। abort () चाहे यह jquery AJAX ऑब्जेक्ट या मूल XMLHTTPRequest ऑब्जेक्ट है।

उदाहरण:

//jQuery ajax
$(document).ready(
    var xhr = $.get('/server');
    setTimeout(function(){xhr.abort();}, 2000);
);

//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);

मुझे मतदान की समस्या थी और एक बार पृष्ठ बंद होने के बाद मतदान मेरे कारण में जारी रहा, इसलिए उपयोगकर्ता एक अपडेट को याद कर देगा क्योंकि पेज बंद होने के बाद अगले 50 सेकंड के लिए एक MySQL मूल्य सेट किया जा रहा था, भले ही मैंने AJAX अनुरोध को मार दिया, मैं एक var सेट करने के लिए $ _SESSION का उपयोग करके चारों ओर अनुमान लगाया गया है, जब तक कि यह समाप्त नहीं हो जाता है, तब तक अपने स्वयं के चुनाव में अपडेट नहीं होता है और एक नया शुरू हो गया है, इसलिए मैंने जो किया वह मेरे डेटाबेस में 0 = ऑफपेज के रूप में एक मान निर्धारित किया गया था, जबकि मैं हूं मतदान मैं उस पंक्ति से पूछता हूं और झूठी वापसी करता हूं; जब मतदान में पूछताछ के रूप में यह 0 है तो आप वर्तमान मूल्यों को स्पष्ट रूप से प्राप्त करेंगे ...

मुझे आशा है कि इससे मदद मिलेगी


मैंने एक demo साझा किया है जो दर्शाता है कि AJAX अनुरोध को कैसे रद्द किया जाए - यदि सर्वर को पूर्व निर्धारित प्रतीक्षा समय के भीतर सर्वर से वापस नहीं किया जाता है।

एचटीएमएल:

<div id="info"></div>

जेएस कोड:

var isDataReceived= false, waitTime= 1000; 
$(function() {
    // Ajax request sent.
     var xhr= $.ajax({
      url: 'http://api.joind.in/v2.1/talks/10889',
      data: {
         format: 'json'
      },     
      dataType: 'jsonp',
      success: function(data) {      
        isDataReceived= true;
        $('#info').text(data.talks[0].talk_title);        
      },
      type: 'GET'
   });
   // Cancel ajax request if data is not loaded within 1sec.
   setTimeout(function(){
     if(!isDataReceived)
     xhr.abort();     
   },waitTime);   
});

यदि xhr.abort(); पेज रीलोड का कारण बनता है,

फिर आप रोकने के लिए निरस्त करने से पहले onreadystatechange सेट कर सकते हैं:

// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();

हमें बस इस समस्या के आसपास काम करना पड़ा और तीन अलग-अलग दृष्टिकोणों का परीक्षण किया।

  1. @meouw द्वारा सुझाए गए अनुरोध को रद्द कर देता है
  2. सभी अनुरोध निष्पादित करें लेकिन केवल अंतिम सबमिट के परिणाम को संसाधित करता है
  3. जब तक कोई दूसरा अभी भी लंबित है तब तक नए अनुरोधों को रोकता है

var Ajax1 = {
  call: function() {
    if (typeof this.xhr !== 'undefined')
      this.xhr.abort();
    this.xhr = $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        //process response
      }
    });
  }
};
var Ajax2 = {
  counter: 0,
  call: function() {
    var self = this,
      seq = ++this.counter;
    $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        if (seq === self.counter) {
          //process response
        }
      }
    });
  }
};
var Ajax3 = {
  active: false,
  call: function() {
    if (this.active === false) {
      this.active = true;
      var self = this;
      $.ajax({
        url: 'your/long/running/request/path',
        type: 'GET',
        success: function(data) {
          //process response
        },
        complete: function() {
          self.active = false;
        }
      });
    }
  }
};
$(function() {
  $('#button').click(function(e) {
    Ajax3.call();
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />

हमारे मामले में हमने दृष्टिकोण # 3 का उपयोग करने का निर्णय लिया क्योंकि यह सर्वर के लिए कम लोड उत्पन्न करता है। लेकिन मैं 100% निश्चित नहीं हूं अगर jQuery .complete () - विधि की कॉल की गारंटी देता है, तो यह एक डेडलॉक स्थिति उत्पन्न कर सकता है। हमारे परीक्षणों में हम ऐसी स्थिति को पुन: उत्पन्न नहीं कर सके।







ajax