Cara menggunakan AJAXSTOP pada JavaScript

I would do something like this in include.js:

(function(){
    window._allAjaxRequestsHaveStopped = false;
    var interval;
    $(document).ajaxStop(function() {
        if (interval) {
            clearInterval(interval);
            interval = null;
        }
        interval = setTimeout(function(){
            window._allAjaxRequestsHaveStopped = true;
        }, 500);
    });
    $(document).ajaxStart(function() {
        window._allAjaxRequestsHaveStopped = false;
        if (interval) {
            clearInterval(interval);
            interval = null;
        }
    });
})();

This sets a (hopefully unique) variable to the window object that can be later retrieved. This also waits a little longer incase there is another request after the previous batch ended.

In CasperJS you would probably do something like the following to wait for the change in the request status. This uses adds a new function to the casper object and uses casper.waitFor() internally to check the change.

casper.waitForAjaxStop = function(then, onTimeout, timeout){
    return this.waitFor(function(){
        return this.evaluate(function(){
            return window._allAjaxRequestsHaveStopped;
        });
    }, then, onTimeout, timeout);
};

And use it like this:

casper.start(url).waitForAjaxStop().then(function(){
    // do something
}).run();

or this:

casper.start(url).thenClick(selector).waitForAjaxStop().then(function(){
    // do something
}).run();

Saya memiliki widget yang memiliki kontrol javascript yang menyertainya.

Jika widget hadir saat halaman admin widget dimuat, kontrol berfungsi dengan benar.

Ketika saya menambahkan widget baru, mereka tidak berfungsi dengan benar, saya mendapatkan markup, tetapi tidak ada efek javascript yang berlaku.

Jika saya menyimpan widget baru, ketika formulir dimuat kembali, kontrol dibuat dengan benar dan sekarang berfungsi.

Menyegarkan halaman juga memperbaiki masalah, tetapi hanya untuk widget yang ada. Widget baru masih memiliki masalah ini.

Secara khusus saya menjalankan pilih pada input pilih pada titik-titik ini:

  • dokumen siap
  • Lengkap ajax

Saya telah memverifikasi bahwa kode saya dijalankan pada setiap acara seperti yang diinginkan, tetapi hasilnya tidak seperti yang diharapkan.

Berikut ini adalah plugin pengujian yang menunjukkan masalah ini:

https://gist.github.com/Tarendai/8466299

Anda akan melihat saya memiliki penghitung yang bertambah dengan setiap elemen pilih yang ditemukannya dapat dikonversi.

Catatan:

  • Ketika halaman widget dimuat, saya bisa melihat penghitung meningkat di konsol JS seperti yang diharapkan
  • Ketika saya menambahkan widget baru, kode dijalankan, namun gagal menemukan elemen pilih yang dapat dijalankan, seperti yang ditunjukkan oleh found.length menjadi 0. Ini tidak boleh terjadi, karena setiap widget baru dari jenis itu harus memiliki elemen pilih
  • elemen pilih memiliki kelas untuk mengidentifikasi mereka, kelas ini dihapus setelah perpustakaan pilihize diterapkan untuk mencegah duplikasi dan pemrosesan ulang pada widget yang ada.
  • Sebelum menggunakan selectize, saya menggunakan Select2, yang memiliki masalah yang sama
  • Mengomentari kode AJAX, saya berharap widget baru memiliki input pilih standar. Mereka tidak. Saya tidak tahu mengapa ini terjadi

Jadi, bagaimana cara membuat kontrol pilih bekerja tanpa menyuruh pengguna menyegarkan / mengklik simpan sebelum membuat perubahan?

Cara menggunakan AJAXSTOP pada JavaScript


Dengan menggunakan jQuery, bagaimana saya bisa membatalkan / membatalkan permintaan Ajax yang belum saya terima jawabannya?



Jawaban:


Sebagian besar metode jQuery Ajax mengembalikan objek XMLHttpRequest (atau yang setara), jadi Anda bisa menggunakannya abort().

Lihat dokumentasi:

  • Metode abort ( MSDN ). Membatalkan permintaan HTTP saat ini.
  • batalkan () ( MDN ). Jika permintaan sudah dikirim, metode ini akan membatalkan permintaan.
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()

UPDATE: Pada jQuery 1.5 objek yang dikembalikan adalah pembungkus untuk objek XMLHttpRequest asli yang disebut jqXHR. Objek ini muncul untuk mengekspos semua properti dan metode asli sehingga contoh di atas masih berfungsi. Lihat Objek jqXHR (dokumentasi API jQuery).

UPDATE 2: Pada jQuery 3, metode ajax sekarang mengembalikan janji dengan metode tambahan (seperti batalkan), jadi kode di atas masih berfungsi, meskipun objek yang dikembalikan bukan xhrlagi. Lihat blog 3.0 di sini .

UPDATE 3 : xhr.abort()masih berfungsi di jQuery 3.x. Jangan menganggap pembaruan 2 sudah benar. Info lebih lanjut tentang repositori jQuery Github .







Anda tidak dapat mengingat permintaan tetapi Anda dapat menetapkan nilai batas waktu setelah mana tanggapan akan diabaikan. Lihat halaman ini untuk opsi jquery AJAX. Saya percaya bahwa panggilan balik kesalahan Anda akan dipanggil jika periode batas waktu terlampaui. Sudah ada batas waktu default pada setiap permintaan AJAX.

Anda juga dapat menggunakan batalkan () metode pada objek permintaan tapi, sementara itu akan menyebabkan klien untuk berhenti mendengarkan untuk acara tersebut, itu mungkin mungkin tidak akan menghentikan server dari memprosesnya.


Ini asinkron permintaan yang tidak , artinya setelah dikirim, itu ada.

Jika server Anda memulai operasi yang sangat mahal karena permintaan AJAX, yang terbaik yang dapat Anda lakukan adalah membuka server Anda untuk mendengarkan permintaan pembatalan, dan mengirim permintaan AJAX terpisah yang memberitahukan server untuk menghentikan apa pun yang dilakukannya.

Jika tidak, abaikan saja respons AJAX.







Simpan panggilan yang Anda lakukan dalam array, lalu panggil xhr.abort () di masing-masingnya.

CAVEAT BESAR: Anda dapat membatalkan permintaan, tetapi itu hanya sisi klien. Sisi server masih dapat memproses permintaan. Jika Anda menggunakan sesuatu seperti PHP atau ASP dengan data sesi, data sesi dikunci sampai ajax selesai. Jadi, agar pengguna dapat terus menjelajahi situs web, Anda harus menelepon session_write_close (). Ini menyimpan sesi dan membuka kunci sehingga halaman lain yang menunggu untuk melanjutkan akan dilanjutkan. Tanpa ini, beberapa halaman dapat menunggu kunci dihapus.



Permintaan AJAX mungkin tidak lengkap dalam urutan dimulai. Alih-alih membatalkan, Anda dapat memilih untuk mengabaikan semua respons AJAX kecuali yang paling baru:

  • Buat penghitung
  • Tambahkan penghitung saat Anda memulai permintaan AJAX
  • Gunakan nilai penghitung saat ini untuk "mencap" permintaan
  • Dalam panggilan balik sukses membandingkan cap dengan counter untuk memeriksa apakah itu permintaan terbaru

Garis besar kode yang kasar:

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

Demo di jsFiddle



Kami hanya harus mengatasi masalah ini dan menguji tiga pendekatan yang berbeda.

  1. membatalkan permintaan seperti yang disarankan oleh @meouw
  2. melaksanakan semua permintaan tetapi hanya memproses hasil dari pengiriman terakhir
  3. Mencegah permintaan baru selama yang lain masih menunggu

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();
  });
})
 src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
 id="button" type="button" value="click" />

Dalam kasus kami, kami memutuskan untuk menggunakan pendekatan # 3 karena menghasilkan lebih sedikit beban untuk server. Tapi saya tidak 100% yakin jika jQuery menjamin panggilan metode .complete () -, ini bisa menghasilkan situasi jalan buntu. Dalam pengujian kami, kami tidak dapat mereproduksi situasi seperti itu.


Itu selalu praktik terbaik untuk melakukan sesuatu seperti ini.

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

Tetapi jauh lebih baik jika Anda memeriksa pernyataan if untuk memeriksa apakah permintaan ajax adalah nol atau tidak.



Panggil saja xhr. batalkan () apakah itu objek jquery ajax atau objek XMLHTTPRequest asli.

contoh:

//jQuery ajax
$(document).ready(function(){
    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);


Saya sedang melakukan solusi pencarian langsung dan perlu membatalkan permintaan yang tertunda yang mungkin memakan waktu lebih lama dari permintaan terbaru / terbaru.

Dalam kasus saya, saya menggunakan sesuatu seperti ini:

//On document ready
var ajax_inprocess = false;

$(document).ajaxStart(function() {
ajax_inprocess = true;
});

$(document).ajaxStop(function() {
ajax_inprocess = false;
});

//Snippet from live search function
if (ajax_inprocess == true)
{
    request.abort();
}
//Call for new request 


Seperti yang dicatat oleh banyak orang di utas, hanya karena permintaan dibatalkan di sisi klien, server masih akan memproses permintaan tersebut. Ini menciptakan beban yang tidak perlu di server karena melakukan pekerjaan yang kami berhenti mendengarkan di front-end.

Masalah yang saya coba selesaikan (yang mungkin juga dijalankan oleh orang lain) adalah ketika pengguna memasukkan informasi dalam bidang input, saya ingin menjalankan permintaan untuk jenis nuansa Google Instan.

Untuk menghindari memecat permintaan yang tidak perlu dan untuk menjaga kenyamanan front-end, saya melakukan hal berikut:

var xhrQueue = [];
var xhrCount = 0;

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

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

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

    }, 150);

});

Ini pada dasarnya akan mengirim satu permintaan setiap 150ms (variabel yang dapat Anda sesuaikan untuk kebutuhan Anda sendiri). Jika Anda mengalami kesulitan memahami apa yang sebenarnya terjadi di sini, log xhrCountdan xhrQueueke konsol sebelum jika blok.


Cukup gunakan ajax.abort () misalnya Anda dapat membatalkan permintaan ajax yang tertunda sebelum mengirim yang lain seperti ini

//check for existing ajax request
if(ajax){ 
 ajax.abort();
 }
//then you make another ajax request
$.ajax(
 //your code here
  );


Anda dapat membatalkan panggilan ajax berkelanjutan dengan menggunakan ini

<input id="searchbox" name="searchbox" type="text" />

<script src="http://code.jquery.com/jquery-1.11.0.min.js">script>

<script type="text/javascript">
     var request = null;
        $('#searchbox').keyup(function () {
            var id = $(this).val();
            request = $.ajax({
                type: "POST", //TODO: Must be changed to POST
                url: "index.php",
                data: {'id':id},
                success: function () {

                },
                beforeSend: function () {
                    if (request !== null) {
                        request.abort();
                    }
                }
            });
        });

script>


tidak ada cara yang dapat diandalkan untuk melakukannya, dan saya bahkan tidak akan mencobanya, begitu permintaan sedang berjalan; satu - satunya cara untuk bereaksi secara wajar adalah dengan mengabaikan respons.

dalam kebanyakan kasus, itu dapat terjadi dalam situasi seperti: pengguna mengklik terlalu sering pada tombol yang memicu banyak XHR berturut-turut, di sini Anda memiliki banyak pilihan, baik memblokir tombol sampai XHR dikembalikan, atau bahkan tidak memicu XHR baru sementara yang lain sedang menjalankan petunjuk pengguna untuk bersandar - atau membuang respons XHR yang tertunda kecuali yang terbaru.


Kode berikut menunjukkan memulai serta membatalkan permintaan Ajax:

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();


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



Saya memiliki masalah pemungutan suara dan setelah halaman ditutup, pemungutan suara berlanjut sehingga karena saya pengguna akan melewatkan pembaruan karena nilai mysql sedang ditetapkan untuk 50 detik berikutnya setelah penutupan halaman, meskipun saya membunuh permintaan ajax, saya mencari tahu, menggunakan $ _SESSION untuk menetapkan var tidak akan memperbarui dalam polling sendiri sampai berakhir dan yang baru telah dimulai, jadi apa yang saya lakukan adalah menetapkan nilai dalam database saya sebagai 0 = offpage, sementara saya polling, saya query baris itu dan mengembalikan false; saat ini 0 karena kueri dalam polling akan memberi Anda nilai saat ini jelas ...

Saya harap ini membantu


Jika xhr.abort(); menyebabkan pemuatan ulang halaman,

Kemudian Anda dapat mengatur onreadystatechangesebelum batal untuk mencegah:

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


Saya telah membagikan demo yang menunjukkan cara membatalkan permintaan AJAX - jika data tidak dikembalikan dari server dalam waktu tunggu yang telah ditentukan.

HTML:

<div id="info">div>

KODE JS:

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