Pergunta

Estou escrevendo um webapp (Apenas compatível com o Firefox) que usa longas pesquisas (através das habilidades do Ajax da JQuery) para enviar atualizações constantes mais ou menos do servidor para o cliente. Estou preocupado com os efeitos de deixar isso por longos períodos de tempo, digamos, o dia todo ou durante a noite. O esqueleto de código básico é o seguinte:

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

(O meio segundo "sono" é para que o cliente não martele o servidor se as atualizações voltarem ao cliente rapidamente - o que geralmente é.)

Depois de deixar isso correndo durante a noite, tende a fazer o Firefox rastejar. Eu estava pensando que isso poderia ser parcialmente causado por uma grande profundidade de pilha, pois basicamente escrevi uma função infinitamente recursiva. No entanto, se eu usar o Firebug e jogar um ponto de interrupção em fetch, parece que esse não é o caso. A pilha que o Firebug me mostra tem apenas 4 ou 5 quadros de profundidade, mesmo depois de uma hora.

Uma das soluções que estou considerando é mudar minha função recursiva para uma iterativa, mas não consigo descobrir como inseriria o atraso entre os pedidos do Ajax sem girar. Eu olhei para o JS 1.7 "rendimento" palavra -chave Mas não consigo entender bem, para descobrir se é o que eu preciso aqui.

A melhor solução é apenas para fazer uma atualização difícil na página periodicamente, digamos, uma vez a cada hora? Existe um padrão de design melhor/mais magro que não se machuca no navegador, mesmo depois de correr por 8 ou 12 horas? Ou devo apenas pular a pesquisa longa e usar um padrão de "atualização constante" diferente, pois geralmente sei com que frequência o servidor terá uma resposta para mim?

Foi útil?

Solução

Também é possível que seja Firebug. Você está console.Ginging Stuffing, o que significa que você provavelmente tem uma guia de monitor de rede aberta etc., o que significa que todas as solicitações são armazenadas na memória.

Tente desativá -lo, veja se isso ajuda.

Outras dicas

Eu suspeito que a memória esteja vazando de processResults().

Eu tenho usado um código muito semelhante ao seu em um aplicativo da Web de longa duração, que pode ser executado ininterrupto por semanas sem uma atualização de página.

Sua pilha não deve ser profunda, porque fetch() retorna imediatamente. Você não tem um loop infinitamente recursivo.

Você pode querer usar o Firefox Monitor de vazamento complementar Para ajudá -lo a encontrar vazamentos de memória.

A profundidade da pilha de 4-5 está correta. setTimeout e $.ajax são chamadas assíncronas, que retornam imediatamente. O retorno de chamada é mais tarde chamado pelo navegador com uma pilha de chamadas vazias. Como você não pode implementar longas pesquisas de maneira síncrona, você deve usar essa abordagem recursiva. Não há como torná -lo iterativo.

Suspeito que o motivo dessa desaceleração seja que seu código tenha um vazamento de memória. O vazamento poderia estar em $.ajax por jQuery (muito improvável) ou em seu processResults ligar.

É uma má ideia ligar fetch() de dentro do próprio método. A recursividade é melhor usada quando você espera que em algum momento o método atinja um fim e os resultados começarão a ser enviados ao chamador. O problema é que, quando você chama o método de forma recursiva, ele mantém o método do chamador aberto e usando a memória. Se você tem apenas 3-4 quadros de profundidade, é porque o jQuery ou o navegador estão de alguma forma "consertando" o que você fez.

Reulsos recentes do jQuery suportam a oferta longa por padrão. Dessa forma, você pode ter certeza de que o YHOU não está dependendo da inteligência do navegador para lidar com sua chamada recursiva infinita. Ao ligar para o $.ajax() Método Você pode usar o código abaixo para fazer uma longa pesquisa combinada com uma espera segura de 500 milissegundos antes de uma nova chamada.

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

Dessa forma, você pode ter certeza de que o $.ajax() A chamada é fechada antes do início do próximo. Isso pode ser provado adicionando um simples console.log() no prior e outro depois do seu $.ajax() ligar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top