60 votes

Utilisation de setInterval() pour effectuer une interrogation continue simpliste

Pour une application Web simple qui doit actualiser des parties de données présentées à l'utilisateur à des intervalles définis, y a-t-il des inconvénients à simplement utiliser setInterval() pour obtenir un JSON à partir d'un point de terminaison au lieu d'utiliser un cadre d'interrogation approprié ?

Pour l'exemple, disons que j'actualise l'état d'un travail de traitement toutes les 5 secondes.

84voto

Felix Kling Points 247451

De mon commentaire :

J'utiliserais setTimeout [docs] et l'appellerais toujours lorsque la réponse précédente était reçue. De cette façon, vous évitez une éventuelle congestion ou un empilement de fonctions ou quel que soit le nom que vous souhaitez lui donner, au cas où une demande/réponse prendrait plus de temps que votre intervalle.

Donc quelque chose comme ça :

 function refresh() {
    // make Ajax call here, inside the callback call:
    setTimeout(refresh, 5000);
    // ...
}

// initial call, or just call refresh directly
setTimeout(refresh, 5000);

17voto

bschlueter Points 2010

Une simple fonction de sondage non bloquante peut être implémentée dans les navigateurs récents utilisant Promises :

 var sleep = time => new Promise(resolve => setTimeout(resolve, time))
var poll = (promiseFn, time) => promiseFn().then(
             sleep(time).then(() => poll(promiseFn, time)))

// Greet the World every second
poll(() => new Promise(() => console.log('Hello World!')), 1000)

6voto

Scen Points 706

Vous pouvez faire comme ceci :

 var i = 0, loop_length = 50, loop_speed = 100;

function loop(){
    i+= 1; 
    /* Here is your code. Balabala...*/
    if (i===loop_length) clearInterval(handler);
}

var handler = setInterval(loop, loop_speed);

1voto

allenyllee Points 151

Modifiez simplement la réponse de @bschlueter , et oui, vous pouvez annuler cette fonction de sondage en appelant cancelCallback()

 let cancelCallback = () => {};

var sleep = (period) => {
  return new Promise((resolve) => {
    cancelCallback = () => {
      console.log("Canceling...");
      // send cancel message...
      return resolve('Canceled');
    }
    setTimeout(() => {
      resolve("tick");
    }, period)
  })
}

var poll = (promiseFn, period, timeout) => promiseFn().then(() => {
  let asleep = async(period) => {
    let respond = await sleep(period);
    // if you need to do something as soon as sleep finished
    console.log("sleep just finished, do something...");
    return respond;
  }


  // just check if cancelCallback is empty function, 
  // if yes, set a time out to run cancelCallback()
  if (cancelCallback.toString() === "() => {}") {
    console.log("set timout to run cancelCallback()")
    setTimeout(() => {
      cancelCallback()
    }, timeout);
  }

  asleep(period).then((respond) => {
    // check if sleep canceled, if not, continue to poll
    if (respond !== 'Canceled') {
      poll(promiseFn, period);
    } else {
      console.log(respond);
    }
  })

  // do something1...
  console.log("do something1...");

})


poll(() => new Promise((resolve) => {
  console.log('Hello World!');
  resolve(); //you need resolve to jump into .then()
}), 3000, 10000);

// do something2...
console.log("do something2....")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X