Pregunta

Estoy escribiendo una aplicación web ( compatible con Firefox solamente ), que utiliza el sondeo de largo (a través de habilidades ajax de jQuery) para enviar actualizaciones más o menos constante desde el servidor al cliente. Estoy preocupado por los efectos de dejar esta en funcionamiento durante largos periodos de tiempo, por ejemplo, todo el día o durante la noche. El esqueleto de código básica es la siguiente:

function processResults(xml)
{
    // do stuff with the xml from the server
}

function fetch()
{
    setTimeout(function ()
    {
        $.ajax({
            type: 'GET',
            url: 'foo/bar/baz',
            dataType: 'xml',
            success: function (xml)
            {
                processResults(xml);
                fetch();
            },
            error: function (xhr, type, exception)
            {
                if (xhr.status === 0)
                {
                console.log('XMLHttpRequest cancelled');
                }
                else
                {
                    console.debug(xhr);
                    fetch();
                }
            }
        });
    }, 500);
}

(El medio segundo "sueño" es para que el cliente no clavar el servidor si los cambios están llegando de nuevo al cliente con rapidez -. Que por lo general son)

Después de salir de esta noche en ejecución, que tiende a hacer rastreo Firefox. Había estado pensando que esto podría deberse, en parte por una gran profundidad de la pila ya que he escrito básicamente una función infinitamente recursiva. Sin embargo, si uso Firebug y lanzo un punto de interrupción en fetch, parece que este no es el caso. La pila que Firebug me muestra es sólo alrededor de 4 o 5 cuadros de profundidad, incluso después de una hora.

Una de las soluciones que estoy considerando es el cambio de mi función recursiva para un proceso iterativo, pero no puedo averiguar cómo iba a insertar el retardo entre las peticiones Ajax sin exprimir . He mirado en el JS 1.7 "rendimiento" palabra clave pero no puedo bastante envoltura mi cabeza alrededor de ella, para averiguar si es lo que necesito aquí.

Es la mejor solución sólo para hacer una actualización de disco en la página periódicamente, por ejemplo, una vez cada hora? ¿Hay un patrón de diseño más delgado mejor / más largo de votación que no va a poner un daño en el navegador, incluso después de correr durante 8 ó 12 horas? ¿O debo saltar el tiempo de votación en conjunto y utilizar un patrón diferente "actualización constante" ya que normalmente saber con qué frecuencia el servidor tendrá una respuesta para mí?

¿Fue útil?

Solución

También es posible que se trata de FireBug. Estás console.logging cosas, lo que significa que probablemente tiene una pestaña monitor de red abierta, etc, lo que significa que cada petición se almacena en la memoria.

Trate de su desactivación, ver si eso ayuda.

Otros consejos

Sospecho que hay una fuga de memoria processResults().

He estado usando código muy similar a la suya en una aplicación web largo de votación, que es capaz de funcionar sin interrupción durante semanas sin una actualización de la página.

Su pila no debe ser profunda, porque los rendimientos fetch() inmediatamente. Usted no tiene un bucle infinito recursiva.

Es posible que desee utilizar el Firefox Monitor de Fugas Add-on para ayudarle a encontrar pérdidas de memoria.

La profundidad de la pila de 4-5 es correcta. setTimeout y $.ajax son llamadas asíncronas, que devuelven inmediatamente. La devolución de llamada se llamó más tarde por el navegador con una pila de llamadas vacía. Como no se puede poner en práctica sondeo largo de una manera síncrona, debe utilizar este enfoque recursivo. No hay manera para que sea iterativo.

sospecho que la razón de esta desaceleración es que el código tiene una pérdida de memoria. La fuga o bien podría estar en $.ajax por jQuery (muy poco probable), o en su llamada processResults.

Es una mala idea llamar fetch() desde el interior del propio método. Recursividad se utiliza mejor cuando se espera que en algún momento el método llegará a su fin y los resultados se comenzará a enviar a la persona que llama. La cosa es que, cuando se llama al método recursiva que mantiene la memoria abierta y utilizando el método de la persona que llama. Si usted es sólo 3-4 marcos de profundidad, es porque jQuery o el navegador son de alguna manera "arreglar" lo que ha hecho.

Los lanzamientos recientes de apoyo jQuery largo de votación de forma predeterminada. De esta manera usted puede estar seguro de que no yhou deppending en la inteligencia de su navegador para hacer frente a su llamada recursiva infinita. Al llamar al método $.ajax() podría utilizar el siguiente código para hacer una larga encuesta combinada con una espera de seguridad de 500 milisegundos antes de que una nueva llamada.

function myLongPoll(){
    setTimeout(function(){
        $.ajax({
            type:'POST',
            dataType: 'JSON',
            url: 'http://my.domain.com/action',
            data: {},
            cache: false,
            success:function(data){

                //do something with the result

            },
            complete: myLongPoll, 
            async : false,
            timeout: 5000
        });
   //Doesn't matter how long it took the ajax call, 1 milisec or 
   //5 seconds (timeout), the next call will only happen after 2 seconds
   }, 2000);

De esta manera usted puede estar seguro de que la llamada $.ajax() se cierra antes de las próximas se parte. Esto puede demostrarse mediante la adición de un console.log() sencilla en el antes y otro después de su llamada $.ajax().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top