jQuery, exemple de sondage simple


105

J'apprends jQuery et j'essaie de trouver un exemple de code simple qui interrogera une API pour une condition. (c.-à-d. demander une page Web toutes les quelques secondes et traiter les résultats)

Je suis familier avec la façon de faire AJAX dans jQuery, je n'arrive tout simplement pas à trouver le moyen "approprié" de le faire exécuter sur un "timer".

Réponses:


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

4
certaines personnes ont utilisé setTimeoutet certains ont utilisé setInterval. Pourquoi l'un serait-il préféré à l'autre?
Mike

36
setinterval ferait un appel ajax toutes les 5 secondes quoi qu'il arrive. la façon dont je l'ai écrit (ce que je crois est une bonne pratique) attendra les résultats PUIS faire une autre requête ajax 5 secondes plus tard. il y a des moments où j'utiliserais setinterval, mais ce n'est pas l'un d'entre eux. nous ne devrions pas faire de nouvelles demandes jusqu'à ce que nous obtenions les résultats de la dernière demande
Johnny Craig

107
Attention cependant, le code suggéré arrêtera d'interroger si une seule demande échoue. Dans un scénario typique, vous voudrez probablement continuer à interroger de toute façon. Je n'aurais pas setTimeoutdans le gestionnaire de succès mais enchaînez toujours l'appel ajax avec jQuery . Comme ça: $.post('ajax/test.html') .done(function(data) { /* process */ }) .always(function() { setTimeout(doPoll, 5000); });
Mårten Wikström

6
Il n'y a pas d'optimisation des appels de fin. Cela ne ferait que continuer à augmenter la pile d'appels de fonction. L'utilisation d'un modèle de trampoline est recommandée.
Boopathi Rajaa

8
@BoopathiRajaa veuillez fournir un exemple d'un tel modèle de trampoline.
Santa

60

Voici un article utile sur l'interrogation longue (requête HTTP de longue durée) à l'aide de jQuery. Un extrait de code dérivé de cet article:

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

Cela fera la demande suivante seulement une fois la demande ajax terminée.

Une variante de ce qui précède qui s'exécutera immédiatement la première fois qu'elle sera appelée avant d'honorer l'intervalle d'attente / de temporisation.

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

Existe-t-il un moyen d'annuler l'interrogation ou de lui signaler son arrêt?
Tal

Comment effacer le délai d'attente si le résultat attendu est obtenu du serveur?
abhishek77 du

Vous pouvez effacer le délai comme dans cet exemple: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
Ne cliquez pas sur le lien techoctave.com ci-dessus. Essaie de faire toutes sortes de choses désagréables
Siddharth Ram

13

Depuis 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);
  • N'utilise pas la récursivité (la pile de fonctions n'est pas affectée).
  • Ne souffre pas là où setTimeout-récursivité doit être optimisé pour les appels de fin.

Ravi de voir une solution ES6!
PHearst

Qu'est-ce qui en fait une solution ES6 Boopathi Rajaa, setInterval ()?
Halil

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

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

3
Remarque: vous pouvez utiliser cette syntaxesetInterval(poll, 5000);
R3tep

7
function make_call()
{
  // do the request

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

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

2

jQuery.Deferred () peut simplifier la gestion du séquençage asynchrone et de la gestion des erreurs.

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
    }

C'est une approche élégante, mais il y a des pièges ...

  • Si vous ne voulez pas que a then()tombe immédiatement, le rappel doit renvoyer un autre objet alors utilisable (probablement un autre Deferred), ce que font les deux lignes sleep et ajax.
  • Les autres sont trop embarrassants pour l'admettre. :)


Mon commentaire de "récursivité itérative" peut être un peu trompeur. Il n'y a pas de récursion réelle ici puisque l'appel "récursif" se produit à partir d'un rappel anonyme - après initiate_pollingavoir été exécuté jusqu'à la fin.
Brent Bradburn

Dans les derniers navigateurs, vous n'avez plus besoin de jQuery pour faire cela - voir ma réponse ici: stackoverflow.com/a/48728503/86967
Brent Bradburn

Délai d'expiration purement JavaScript:new Promise( resolve => setTimeout(resolve,1000) ).then( () => alert("done") )
Brent Bradburn

Async Recursion Is Iteration
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

Cette solution:

  1. a un délai d'expiration
  2. l'interrogation fonctionne également après une réponse d'erreur

La version minimale de jQuery est 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()
})
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.