web-dev-qa-db-fra.com

Définir un délai dans une fonction jQuery/Ajax répétitive

J'essaie d'ajouter un délai à une requête répétable.

J'ai découvert que le retard n'est pas celui à utiliser ici. Au lieu de cela, je devrais aller avec setInterval ou setTimeout. J'ai essayé les deux, sans aucune chance.

Voici mon code:

<?php 
include("includes/dbconf.php");

$strSQL = mysql_query("SELECT workerID FROM workers ORDER BY workerID ASC");
while($row = mysql_fetch_assoc($strSQL)) {
?>
<script id="source" language="javascript" type="text/javascript">

  $(setInterval(function ()
  {
    $.ajax({                                      
      cache: false,
      url: 'ajax2.php',        
      data: "workerID=<?=$row['workerID'];?>",
      dataType: 'json',    
      success: function(data)
      {
        var id = data[0];              //get id
        var vname = data[1];           //get name
        //--------------------------------------------------------------------
        // 3) Update html content
        //--------------------------------------------------------------------
        $('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
      } 
    });
  }),800); 

  </script>
<?php
}
?>
<div id="output"></div>

Le code fonctionne bien, il affiche le résultat comme demandé. C'est juste des charges sans délai. Le délai d'attente et/ou l'intervalle ne semble pas fonctionner. 

Quelqu'un sait ce que je fais mal?

10
Jeroen

Je n'ai jamais compris pourquoi les gens ajoutent toujours leurs demandes AJAX à intervalles réguliers au lieu de laisser les appels réussis AJAX s'appeler tout seuls, tout en risquant de surcharger le serveur avec plusieurs demandes et en ne faisant pas un autre appel une fois. vous avez réussi à revenir.

Dans cette optique, j'aime écrire des solutions où les appels AJAX s'appellent simplement une fois l'appel terminé, quelque chose comme:

// set your delay here, 2 seconds as an example...
var my_delay = 2000;

// call your ajax function when the document is ready...
$(function() {
    callAjax();
});

// function that processes your ajax calls...
function callAjax() {
    $.ajax({
        // ajax parameters here...
        // ...
        success: function() {
            setTimeout(callAjax, my_delay);
        }
    });
}

J'espère que cela a du sens! :)

Mettre à jour:

Après avoir examiné à nouveau cette question, il a été porté à mon attention qu'il y avait également un problème dans le code PHP de la question initiale que je devais clarifier et aborder.

Bien que le script ci-dessus fonctionne parfaitement pour créer un délai entre les appels AJAX, une fois ajouté au code PHP de la publication d'origine, le script sera simplement echo 'out autant de fois que le nombre de lignes. la requête SQL sélectionne, crée plusieurs fonctions avec le même nom et effectue éventuellement tous les appels AJAX simultanément ... pas très cool du tout ...

Dans cet esprit, je propose la solution supplémentaire suivante: créer une array avec le script PHP pouvant être digéré par l'élément JavaScript un élément à la fois pour obtenir le résultat souhaité. Tout d’abord, le PHP pour construire la chaîne de tableau JavaScript ...

<?php 
    include("includes/configuratie.php");
    $strSQL = mysql_query("SELECT workerID FROM tWorkers ORDER BY workerID ASC");

    // build the array for the JavaScript, needs to be a string...
    $javascript_array = '[';
    $delimiter = '';
    while($row = mysql_fetch_assoc($strSQL))
    {
        $javascript_array .= $delimiter . '"'. $row['workerID'] .'"'; // with quotes
        $delimiter = ',';
    }
    $javascript_array .= ']';
    // should create an array string, something like:
    // ["1","2","3"]
?>

Ensuite, le JavaScript pour digérer et traiter le tableau que nous venons de créer ...

// set your delay here, 2 seconds as an example...
var my_delay = 2000;

// add your JavaScript array here too...
var my_row_ids = <?php echo $javascript_array; ?>;

// call your ajax function when the document is ready...
$(function() {
    callAjax();
});

// function that processes your ajax calls...
function callAjax() {
    // check to see if there are id's remaining...
    if (my_row_ids.length > 0)
    {
        // get the next id, and remove it from the array...
        var next_id = my_row_ids[0];
        my_row_ids.shift();
        $.ajax({
            cache    : false,
            url      : 'ajax2.php',
            data     : "workerID=" + next_id, // next ID here!
            dataType : 'json',
            success  : function(data) {
                           // do necessary things here...
                           // call your AJAX function again, with delay...
                           setTimeout(callAjax, my_delay);
                       }
        });
    }
}
25
Chris Kempen

Remarque: la réponse de Chris Kempen (ci-dessus) est meilleure. Veuillez utiliser celle-là. Il utilise cette technique dans la routine AJAX. Voir cette réponse pour savoir pourquoi utiliser setTimeout est préférable à setInterval.


//Global var
is_expired = 0;

$(function (){

    var timer = setInterval(doAjax, 800);

    //At some point in future, you may wish to stop this repeating command, thus:
    if (is_expired > 0) {
        clearInterval(timer);
    }

}); //END document.ready

function doAjax() {
    $.ajax({                                      
        cache: false,
        url: 'ajax2.php',        
        data: "workerID=<?=$row['workerID'];?>",
        dataType: 'json',    
        success: function(data) {
            var id = data[0];              //get id
            var vname = data[1];           //get name
            //--------------------------------------------------------------------
            // 3) Update html content
            //--------------------------------------------------------------------
            $('#output').html("<b>id: </b>"+id+"<b> name: </b>"+vname);
        }
    }); //END ajax code block
} //END fn doAjax()
1
gibberish

J'ai conçu une méthode d'encapsulation qui ajoute un délai personnalisé on-top de la méthode par défaut $.ajax. C'est un moyen d'avoir (sur tous jQuery ajax appels) un délai, dans l'ensemble de votre application. 

Très pratique pour simuler une latence aléatoire réelle.

(function(){
  $._ajaxDelayBk = $.ajax; // save reference to the "real" ajax method

 // override the method with a wrapper
  $.ajax = function(){
    var def = new $.Deferred(),
        delay = typeof $.ajax.delay == 'undefined' ? 500 : $.ajax.delay, 
        delayTimeout,
        args = arguments[0];

    // set simulated delay (random) duration
    delayTimeout = setTimeout(function(){
      $._ajaxDelayBk(args)
        .always(def.resolve)
        .done(def.resolve)
        .fail(def.reject)
    }, delay);

    def.abort = function(){
        clearTimeout(delayTimeout);
    };

    return def;
  }
})();

Exemple d'utilisation:

// optional: set a random delay to all `ajax` calls (between 1s-5s)
$.ajax.delay = Math.floor(Math.random() * 5000) + 1000;

var myAjax = $.ajax({url:'http://whatever.com/API/1', timeout:5000})
  .done(function(){ console.log('done', arguments) })
  .fail(function(){ console.log('fail', arguments) })
  .always(function(){ console.log('always', arguments) })

// Can abort the ajax call
// myAjax.abort();
0
vsync