2011-12-30 10 views
11

Para una aplicación web simple que necesita actualizar partes de los datos presentados al usuario en intervalos establecidos, ¿hay algún inconveniente al usar setInterval() para obtener un json de un punto final en lugar de utilizando un marco de votación adecuado?Uso de setInterval() para realizar un sondeo continuo simplista

Por el bien del ejemplo, digamos que estoy actualizando el estado de un trabajo de procesamiento cada 5 segundos.

+6

yo usaría 'setTimeout' y siempre llamarlo cuando se recibió la respuesta anterior. De esta forma evitará la posible congestión o acumulación de funciones o como quiera llamarlo. –

+0

Lo he hecho como @FelixKling dijo y funciona como un encanto. ¡Intentalo! – Alfabravo

+0

¡Impresionante! ¿Puede @FelixKling, podría publicar eso como la respuesta y lo acepto? – Sologoub

Respuesta

25

Desde mi comentario:

me gustaría utilizar setTimeout[docs] y siempre llamarlo cuando se recibió la respuesta anterior. De esta forma evitará la posible congestión o el apilamiento de funciones o lo que sea que quiera llamar, en caso de que una solicitud/respuesta tome más tiempo que su intervalo.

Así que algo como esto:

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

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

Un buen análisis aquí sobre por qué evitar 'setInterval' es una buena idea: http://weblogs.asp.net/bleroy/archive/2009/05/14/setinterval-is-moderately-evil.aspx –

+0

deberíamos usar' setTimeout (refresh, 5000); '¿dos veces? Me refiero a uno después de la llamada inicial y luego de nuevo en la función que se llama? – David

1

Sé que esto es una vieja pregunta, pero tropezó con ella, y en la forma Stackoverflow de hacer las cosas que pensé que podría mejorarlo. Es posible que desee considerar una solución similar a what's described here que se conoce como larga encuesta. O otra solución es WebSockets (una de las mejores implementaciones de websockets con el objetivo principal de trabajar en todos los navegadores) socket.io.

La primera solución se resume básicamente como enviar una sola solicitud AJAX y esperar una respuesta antes de enviar una adicional, luego una vez que se haya entregado la respuesta, ponga en cola la siguiente consulta.

Mientras tanto, en el back-end no devuelve una respuesta hasta que el estado cambie. Entonces, en su escenario, utilizaría un ciclo while que continuaría hasta que el estado cambiara, luego devolvería el estado modificado a la página. Realmente me gusta esta solución. Como indica la respuesta vinculada anteriormente, esto es lo que Facebook hace (o al menos lo ha hecho en el pasado).

socket.io es básicamente la jQuery de Websockets, por lo que cualquiera que sea el navegador en el que se encuentren los usuarios puede establecer una conexión de socket que pueda enviar datos a la página (sin polling). Esto está más cerca de las notificaciones instantáneas de Blackberry, que, si va por un instante, es la mejor solución.

+0

Aunque socket.io podría ser bueno, no es LA solución para websockets simplemente una solución entre muchas. Todos ellos (casi) buenos a su manera y podría considerar diferentes marcos dependiendo de la tarea a resolver. – Uffe

+0

Descuidado, actualizado para reflejar la intención de mencionar socket.io – th3byrdm4n

1

Puede hacer lo mismo que esto:

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); 
2

una función de consulta sencilla de no bloqueo puede ser implementado en los navegadores recientes usando promesas:

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) 
+0

bueno. trabajos. Si después de un tiempo decido detener la ejecución con un clic de botón, por ejemplo, ¿cómo podría hacerlo, por favor? – Marcel

+0

@Marcel Gracias. La respuesta corta es que eso no es posible (https://stackoverflow.com/a/29479435/1054423). – bschlueter

Cuestiones relacionadas