Domanda

Sto scrivendo una webapp ( Firefox compatibile solo ), che utilizza polling lungo (tramite le abilità Ajax di jQuery) per inviare gli aggiornamenti più o meno costante dal server al client. Sono preoccupato per gli effetti di lasciare questa corsa per lunghi periodi di tempo, per esempio, tutto il giorno o durante la notte. Lo scheletro del codice di base è questa:

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

(Il mezzo secondo "sleep" è così che il cliente non martellare il server se gli aggiornamenti sono venuta al client rapidamente -., Che di solito sono)

Dopo aver lasciato questo correre durante la notte, si tende a rendere Firefox strisciare. Avevo pensato che questo potrebbe essere in parte causata da una grande profondità dello stack da quando ho scritto fondamentalmente una funzione infinitamente ricorsiva. Tuttavia, se uso Firebug e gettare un punto di interruzione in fetch, sembra che questo non è il caso. Lo stack che Firebug mi mostra è solo circa 4 o 5 fotogrammi in profondità, anche dopo un'ora.

Una delle soluzioni che sto considerando sta cambiando la mia funzione ricorsiva a un iterativo, ma io non riesco a capire come avrei inserire il ritardo tra le richieste Ajax senza spinning . Ho guardato il JS 1.7 "resa" parola chiave ma non posso avvolgere tutto la mia testa intorno ad esso, per capire se è quello che mi serve qui.

E 'la soluzione migliore solo per fare un aggiornamento forzato sulla pagina periodicamente, per esempio, una volta ogni ora? C'è una migliore / più snella lungo polling modello di progettazione che non mette una ferita sul browser anche dopo l'esecuzione per 8 o 12 ore? O devo solo saltare la lunga polling del tutto e utilizzare un modello diverso "costante aggiornamento" visto che di solito conoscere la frequenza con cui il server avrà una risposta per me?

È stato utile?

Soluzione

E 'anche possibile che si tratta di Firebug. Stai console.logging roba, il che significa che probabilmente avete una scheda monitor di rete aperta, ecc, il che significa che ogni richiesta viene memorizzato nella memoria.

Prova a disabilitarlo, vedere se questo aiuta.

Altri suggerimenti

Ho il sospetto che la memoria perde da processResults().

Sono stato con codice molto simile alla vostra in un'applicazione web-polling lungo, che è in grado di lavorare ininterrottamente per settimane senza un aggiornamento della pagina.

Il tuo stack non dovrebbe essere profondo, perché fetch() ritorna immediatamente. Non si dispone di un ciclo infinitamente ricorsivo.

Si consiglia di utilizzare Firefox Leak Monitor Add-on per aiutarvi a trovare le perdite di memoria.

La profondità pila di 4-5 è corretta. setTimeout e $.ajax sono chiamate asincrone, che restituiscono immediatamente. Il callback viene successivamente chiamato dal browser con uno stack di chiamata vuoto. Dal momento che non è possibile implementare polling lungo in modo sincrono, è necessario utilizzare questo metodo ricorsivo. Non c'è modo di rendere iterativo.

Ho il sospetto che la ragione di questo rallentamento è che il codice ha una perdita di memoria. La perdita potrebbe essere sia in $.ajax da jQuery (molto improbabile) o nella chiamata processResults.

Si tratta di una cattiva idea quella di chiamare fetch() dall'interno del metodo stesso. Ricorsività è meglio utilizzato quando ci si aspetta che ad un certo punto il metodo raggiungerà una fine ed i risultati inizieranno a essere disponibili inviare al chiamante. Il fatto è che, quando si chiama il metodo ricorsivo mantiene il metodo chiamante memoria aperta e l'utilizzo. Se siete solo 3-4 fotogrammi in profondità, è perché jQuery o il browser sono in qualche modo "fissare" quello che hai fatto.

Le versioni recenti di sostegno jquery lungo polling per impostazione predefinita. In questo modo si può essere sicuri che non sono yhou deppending sull'intelligenza del browser per gestire la sua chiamata ricorsiva infinita. Quando si chiama il metodo $.ajax() di fare un lungo sondaggio combinato con un'attesa di sicurezza di 500 millisecondi prima che una nuova chiamata è possibile utilizzare il codice qui sotto.

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

In questo modo si può essere sicuri che la chiamata $.ajax() sia chiuso prima di quello successivo inizia. Questo può essere dimostrato con l'aggiunta di un semplice console.log() alla prima e l'altro dopo la chiamata $.ajax().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top