jQuery, простий приклад опитування


105

Я вивчаю jQuery, і намагаюся знайти простий приклад коду, який опитатиме API для умови. (тобто запитувати веб-сторінку кожні кілька секунд та обробляти результати)

Я знайомий з тим, як робити AJAX в jQuery, я просто не можу знайти "належний" спосіб його виконання на "таймері".

Відповіді:


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

4
деякі користувалися, setTimeoutа деякі використовували setInterval. Чому один віддавав перевагу іншому?
Майк

36
setinterval здійснював би виклик ajax кожні 5 секунд, незалежно від того. так, як це написали (що, я вважаю, є хорошою практикою), чекатимуть результатів, а потім зробимо ще один запит на ajax через 5 секунд. бувають випадки, коли я використовував би setinterval, але це не один із них. ми не повинні робити жодних нових запитів, поки не отримаємо результати від останнього запиту
Johnny Craig

107
Будьте обачні, хоча запропонований код припинить опитування, якщо один запит не вдасться. За типового сценарію, ви, ймовірно, хочете продовжити опитування в будь-якому випадку. У мене не було setTimeoutб обробника успіху, але натомість завжди ланцюжок дзвінків Ajax з jQuery . Ось так: $.post('ajax/test.html') .done(function(data) { /* process */ }) .always(function() { setTimeout(doPoll, 5000); });
Mårten Wikström

6
Немає оптимізації виклику хвоста. Це просто продовжує збільшувати стек викликів функцій. Використання шаблону батута рекомендується.
Boopathi Rajaa

8
@BoopathiRajaa, будь ласка, наведіть приклад такої моделі батута.
Санта,

60

Ось корисна стаття про довге опитування (тривалий HTTP-запит) за допомогою jQuery. Фрагмент коду, отриманий з цієї статті:

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

Наступний запит зробить лише після завершення запиту ajax.

Варіант вищезазначеного, який буде виконаний негайно під час першого виклику перед вшануванням інтервалу очікування / час очікування.

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

Чи є спосіб скасувати опитування або подати сигнал до припинення?
Тал

Як видалити час очікування, якщо очікуваний результат буде отриманий від сервера?
abhishek77in

Ви можете очистити тайм-аут, як у цьому прикладі: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); } })();
Маріус

2
Не натискайте на посилання techoctave.com вище. Намагається робити всілякі неприємні справи
Сіддхарт Рам

13

Від 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);
  • Не використовує рекурсію (стек функцій не впливає).
  • Не страждає там, де setTimeout-рекурсію потрібно оптимізувати хвостовим викликом.

Приємно бачити рішення ES6!
Ферст

Що робить його рішенням ES6 Boopathi Rajaa, setInterval ()?
Халіл

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

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

3
Примітка: Ви можете використовувати цей синтаксисsetInterval(poll, 5000);
R3tep

7
function make_call()
{
  // do the request

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

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

2

jQuery.Deferred () може спростити управління асинхронним послідовністю та обробкою помилок.

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
    }

Це елегантний підхід, але є якісь готчі ...

  • Якщо ви не хочете then()одразу провалитися, зворотний виклик повинен повернути інший об'єкт, що може відвернутись (можливо, інший Deferred), який обидва виконують лінії сну та ajax.
  • Інших занадто соромно визнати. :)

Подібні відповіді за адресою: Відкладено через певний час
Брент Бредберн

Мій "ітеративний рекурс" коментар може бути трохи оманливим. Тут немає фактичної рекурсії, оскільки "рекурсивний" виклик відбувається від анонімного зворотного дзвінка - після того, initiate_pollingяк запущено до завершення.
Брент Бредберн

Чи не в останніх браузерах, ви більше не потрібно JQuery зробити це зробити - дивіться моя відповідь тут: stackoverflow.com/a/48728503/86967
Brent Bradburn

Чистий тайм-аут JavaScript:new Promise( resolve => setTimeout(resolve,1000) ).then( () => alert("done") )
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

Це рішення:

  1. має тайм-аут
  2. опитування працює і після відповіді на помилку

Мінімальна версія jQuery - 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()
})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.