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 les besoins de l'exemple, disons que je rafraîchis l'état d'un travail de traitement toutes les 5 secondes.
De mon commentaire:
J'utiliserais setTimeout
[docs] et appelez-le toujours lorsque la réponse précédente a été reçue. De cette façon, vous évitez la congestion ou l'empilement de fonctions ou tout ce que vous voulez appeler, au cas où une demande/réponse prend 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);
Une simple fonction d'interrogation non bloquante peut être implémentée dans les navigateurs récents à l'aide de 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)
Vous pouvez faire comme ça:
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);
Je sais que c'est une vieille question, mais je suis tombée dessus, et dans la manière de faire StackOverflow, j'ai pensé que je pourrais l'améliorer. Vous voudrez peut-être envisager une solution similaire à ce qui est décrit ici qui est connu sous le nom d'interrogation longue. OR une autre solution est WebSockets (l'une des meilleures implémentations de websockets avec l'objectif principal de travailler sur tous les navigateurs) socket.io .
La première solution est essentiellement résumée lorsque vous envoyez une seule requête AJAX et attendez une réponse avant d'en envoyer une supplémentaire, puis une fois la réponse envoyée, placez la prochaine requête en file d'attente.
Pendant ce temps, sur le backend, vous ne renvoyez pas de réponse tant que le statut n'a pas changé. Ainsi, dans votre scénario, vous utiliseriez une boucle while qui continuerait jusqu'à ce que le statut change, puis renverriez le statut modifié à la page. J'aime vraiment cette solution. Comme l'indique la réponse ci-dessus, c'est ce que Facebook fait (ou du moins a fait dans le passé).
socket.io est fondamentalement la jQuery de Websockets, de sorte que quel que soit le navigateur de vos utilisateurs, vous pouvez établir une connexion socket qui peut pousser des données vers la page (sans interrogation du tout). C'est plus proche des notifications instantanées d'un Blackberry, qui - si vous optez pour l'instant, c'est la meilleure solution.
Modifiez simplement @ réponse de bschlueter , et oui, vous pouvez annuler cette fonction d'interrogation 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....")