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".

Mike
sumber

Jawaban:

140
function doPoll(){
    $.post('ajax/test.html', function(data) {
        alert(data);  // process results here
        setTimeout(doPoll,5000);
    });
}
Johnny Craig
sumber
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
    })
})();
chrisjleu
sumber
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.
Boopathi Rajaa
sumber
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);
asal
sumber
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();
});
PeeHaa
sumber
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. :)
Brent Bradburn
sumber
Jawaban serupa di: Ditunda dalam loop sementara
Brent Bradburn
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);
})();
vaquar khan
sumber
0

Saya membuat plugin JQuery kecil untuk ini. Anda dapat mencobanya:

$.poll('http://my/url', 100, (xhr, status, data) => {
    return data.hello === 'world';
})

https://www.npmjs.com/package/jquerypoll

Sohan
sumber
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()
})
jozo
sumber