2011-07-21 28 views
13

Digamos que tengo algunos datos que necesito obtener del servidor cada 10 segundos. Tendría una función que obtiene los datos a través de AJAX y luego llamar a setTimeout a llamar a esta función una vez más:¿Una llamada de función recursiva 'setTimeout' eventualmente matará al motor JS?

function GetData(){ 
    $.ajax({ 
     url: "data.json", 
     dataType: "json", 
     success: function(data){ 
     // do somthing with the data 

     setTimeout(GetData, 10000); 
     }, 
     error: function(){ 
     setTimeout(GetData, 10000); 
     } 
    }); 
} 

Si alguien sale de la página web abierta todo el día, se podría obtener miles de llamadas a funciones recursivas.

No quiero utilizar setInterval porque eso no tiene en cuenta el retraso de la red. Si la red está ocupada y toma 15 segundos procesar la solicitud, no quiero volver a preguntar antes de obtener el tiempo de espera de AJAX.

¿Cuál es la mejor manera de manejar una función que necesita ser llamada periódicamente?

+0

cada llamada posterior a GetData será completamente independientes entre sí. Después de que se complete cualquier ejecución de ejecución de GetData, se destruirá su contexto y se creará una nueva cuando expire el temporizador. –

+0

esto probablemente causaría problemas para el servidor mucho antes del javascript del lado del cliente. como los otros han mencionado, no tienes un problema de pila de llamadas porque el setTimeout permite que la función regrese y se elimine de la pila. Recursión algorítmica, pero no en realidad. – aepheus

+0

Esta pregunta es exactamente lo que estoy investigando. Gracias por traerlo aquí. – shaosh

Respuesta

21

No hay recursión real, porque se retrasa la llamada a GetData y el contexto JavaScript es destruida en el ínterin. Por lo tanto, no bloqueará el motor JS.

Para su ejemplo de código, esto es básicamente lo que sucederá en el nivel del motor JS:

  1. Inicializar JS motor
  2. Crear contexto función GetData
  3. Ejecutar sentencias GetData incluyendo "setTimeOut"
  4. "setTimeOut" instruye al motor JS para llamar a una función en 10 segundos
  5. Destruye el contexto de la función GetData
  6. En este punto, en términos de uso de la memoria, volvemos al paso 1. La única diferencia es que el motor JS almacenó una referencia a una función y cuándo llamarla (vamos a llamar a estos datos "futura Llamada").
  7. Después de 10 segundos, repita desde el paso 2. "futureCall" se destruye.
+0

¿Es dependiente esta implementación? ¿O está esto en la especificación de JavaScript? – Robert

+0

En la especificación se indica que "nunca destruyas un contexto desde el que se ha llamado a setTimeout". No es una recursividad, por lo que no hay razón para que falle la implementación, incluso las mal codificadas. –

+0

Todavía me estoy volviendo loco ... Así que si supongo que todo en JS se ejecuta como un controlador de eventos, entonces setTimeout solo desencadena otro evento para ser manejado. Obtiene su propia pila/hilo/proceso/memoria/todo. – Robert

Cuestiones relacionadas