jQuery, contoh polling sederhana


105

Saya belajar jQuery, dan saya mencoba menemukan contoh kode sederhana yang akan meminta sebuah API untuk suatu kondisi. (yaitu, minta halaman web setiap beberapa detik dan proses hasilnya)

Saya terbiasa dengan cara melakukan AJAX di jQuery, saya tidak bisa menemukan cara yang "tepat" untuk menjalankannya pada "pengatur waktu".

Jawaban:


140
function doPoll(){
    $.post('ajax/test.html', function(data) {
        alert(data);  // process results here
        setTimeout(doPoll,5000);
    });
}

4
beberapa orang telah menggunakan setTimeoutdan beberapa telah menggunakan setInterval. Mengapa seseorang lebih disukai daripada yang lain?
Mike

36
setinterval akan membuat panggilan ajax setiap 5 detik apa pun yang terjadi. cara menulisnya (yang saya yakini adalah praktik yang baik) akan menunggu hasilnya KEMUDIAN buat permintaan ajax lagi 5 detik kemudian. ada kalanya saya akan menggunakan setinterval, tetapi ini bukan salah satunya. kita tidak boleh membuat permintaan baru sampai kita mendapatkan hasil dari permintaan terakhir
Johnny Craig

107
Harap berhati-hati meskipun kode yang disarankan akan berhenti melakukan polling jika satu permintaan gagal. Dalam skenario umum, Anda mungkin ingin melanjutkan pemungutan suara. Saya tidak akan setTimeoutberada dalam penangan sukses tetapi malah merantai panggilan ajax dengan jQuery selalu . Seperti ini: $.post('ajax/test.html') .done(function(data) { /* process */ }) .always(function() { setTimeout(doPoll, 5000); });
Mårten Wikström

6
Tidak ada optimasi panggilan ekor. Ini hanya akan terus meningkatkan tumpukan panggilan fungsi. Dianjurkan untuk menggunakan pola trampolin.
Boopathi Rajaa

8
@BoopathiRajaa berikan contoh pola trampolin seperti itu.
santa

60

Berikut adalah artikel bermanfaat tentang polling panjang (permintaan HTTP lama) menggunakan jQuery. Cuplikan kode yang berasal dari artikel ini:

(function poll() {
    setTimeout(function() {
        $.ajax({
            url: "/server/api/function",
            type: "GET",
            success: function(data) {
                console.log("polling");
            },
            dataType: "json",
            complete: poll,
            timeout: 2000
        })
    }, 5000);
})();

Ini akan membuat permintaan berikutnya hanya setelah permintaan ajax selesai.

Variasi di atas yang akan langsung dijalankan saat pertama kali dipanggil sebelum mengikuti interval tunggu / waktu tunggu.

(function poll() {
    $.ajax({
        url: "/server/api/function",
        type: "GET",
        success: function(data) {
            console.log("polling");
        },
        dataType: "json",
        complete: setTimeout(function() {poll()}, 5000),
        timeout: 2000
    })
})();

Adakah cara untuk membatalkan polling, atau memberinya sinyal untuk berhenti?
Tal

Bagaimana cara menghapus batas waktu jika hasil yang diharapkan diperoleh dari server?
abhishek77in

Anda dapat menghapus waktu tunggu seperti dalam contoh ini:let is_success = false; (function poll() { let timeout = setTimeout(function() { $.ajax({ url: resp.location, type: "GET", success: function(data) { if(YOUR_CONDITION) { is_success=true; } }, dataType: "json", complete: poll, timeout: 2000 }) }, 5000); if(is_success) { console.log("ending poll"); window.clearTimeout(timeout); } })();
Marius

2
Jangan klik tautan techoctave.com di atas. Mencoba melakukan segala macam hal buruk
Siddharth Ram

13

Dari ES6,

var co = require('co');
var $ = require('jQuery');

// because jquery doesn't support Promises/A+ spec
function ajax(opts) {
  return new Promise(function(resolve, reject) {
    $.extend(opts, {
      success: resolve,
      error: reject
    });
    $.ajax(opts);
  }
}

var poll = function() {
  co(function *() {
    return yield ajax({
      url: '/my-api',
      type: 'json',
      method: 'post'
    });
  }).then(function(response) {
    console.log(response);
  }).catch(function(err) {
    console.log(err);
  });
};

setInterval(poll, 5000);
  • Tidak menggunakan rekursi (tumpukan fungsi tidak terpengaruh).
  • Tidak menderita di mana rekursi setTimeout perlu dioptimalkan panggilan-ekor.

Senang melihat solusi ES6!
PHearst

Apa yang menjadikannya solusi ES6 Boopathi Rajaa, setInterval ()?
Halil

11
function poll(){
    $("ajax.php", function(data){
        //do stuff  
    }); 
}

setInterval(function(){ poll(); }, 5000);

3
Catatan: Anda dapat menggunakan sintaks inisetInterval(poll, 5000);
R3tep

7
function make_call()
{
  // do the request

  setTimeout(function(){ 
    make_call();
  }, 5000);
}

$(document).ready(function() {
  make_call();
});

2

jQuery.Deferred () dapat menyederhanakan pengelolaan pengurutan asinkron dan penanganan error.

polling_active = true // set false to interrupt polling

function initiate_polling()
    {
    $.Deferred().resolve() // optional boilerplate providing the initial 'then()'
    .then( () => $.Deferred( d=>setTimeout(()=>d.resolve(),5000) ) ) // sleep
    .then( () => $.get('/my-api') ) // initiate AJAX
    .then( response =>
        {
        if ( JSON.parse(response).my_result == my_target ) polling_active = false
        if ( ...unhappy... ) return $.Deferred().reject("unhappy") // abort
        if ( polling_active ) initiate_polling() // iterative recursion
        })
    .fail( r => { polling_active=false, alert('failed: '+r) } ) // report errors
    }

Ini adalah pendekatan yang elegan, tetapi ada beberapa gotcha ...

  • Jika Anda tidak ingin then()segera gagal, callback harus mengembalikan objek lain yang dapat digunakan (mungkin yang lainDeferred ), yang sama-sama dilakukan oleh garis sleep dan ajax.
  • Yang lain terlalu malu untuk mengakuinya. :)


Komentar "rekursi berulang" saya mungkin agak menyesatkan. Tidak ada rekursi yang sebenarnya di sini karena panggilan "rekursif" terjadi dari panggilan balik anonim - setelah initiate_pollingdijalankan hingga selesai.
Brent Bradburn

Di browser terbaru, Anda tidak perlu lagi jQuery melakukan ini - lihat jawaban saya di sini: stackoverflow.com/a/48728503/86967
Brent Bradburn

Batas waktu JavaScript murni:new Promise( resolve => setTimeout(resolve,1000) ).then( () => alert("done") )
Brent Bradburn

Rekursi Asinkron Adalah Iterasi
Brent Bradburn

0
(function poll() {
    setTimeout(function() {
        //
        var search = {}
        search["ssn"] = "831-33-6049";
        search["first"] = "Harve";
        search["last"] = "Veum";
        search["gender"] = "M";
        search["street"] = "5017 Ottis Tunnel Apt. 176";
        search["city"] = "Shamrock";
        search["state"] = "OK";
        search["zip"] = "74068";
        search["lat"] = "35.9124";
        search["long"] = "-96.578";
        search["city_pop"] = "111";
        search["job"] = "Higher education careers adviser";
        search["dob"] = "1995-08-14";
        search["acct_num"] = "11220423";
        search["profile"] = "millenials.json";
        search["transnum"] = "9999999";
        search["transdate"] = $("#datepicker").val();
        search["category"] = $("#category").val();
        search["amt"] = $("#amt").val();
        search["row_key"] = "831-33-6049_9999999";



        $.ajax({
            type : "POST",
            headers : {
                contentType : "application/json"
            },
            contentType : "application/json",
            url : "/stream_more",
            data : JSON.stringify(search),
            dataType : 'json',
            complete : poll,
            cache : false,
            timeout : 600000,
            success : function(data) {
                //
                //alert('jax')
                console.log("SUCCESS : ", data);
                //$("#btn-search").prop("disabled", false);
                // $('#feedback').html("");
                for (var i = 0; i < data.length; i++) {
                    //
                    $('#feedback').prepend(
                            '<tr><td>' + data[i].ssn + '</td><td>'
                                    + data[i].transdate + '</td><td>'
                                    + data[i].category + '</td><td>'
                                    + data[i].amt + '</td><td>'
                                    + data[i].purch_prob + '</td><td>'
                                    + data[i].offer + '</td></tr>').html();
                }

            },
            error : function(e) {
                //alert("error" + e);

                var json = "<h4>Ajax Response</h4><pre>" + e.responseText
                        + "</pre>";
                $('#feedback').html(json);

                console.log("ERROR : ", e);
                $("#btn-search").prop("disabled", false);

            }
        });

    }, 3000);
})();


0

Solusi ini:

  1. memiliki waktu tunggu
  2. polling juga berfungsi setelah respons kesalahan

Versi minimum jQuery adalah 1.12

$(document).ready(function () {
  function poll () {
    $.get({
      url: '/api/stream/',
      success: function (data) {
        console.log(data)
      },
      timeout: 10000                    // == 10 seconds timeout
    }).always(function () {
      setTimeout(poll, 30000)           // == 30 seconds polling period
    })
  }

  // start polling
  poll()
})
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.