Question

J'écris une webapp ( Firefox compatible uniquement ) qui utilise de longue interrogation (via les capacités ajax jQuery) pour envoyer des mises à jour plus ou moins constant du serveur au client. Je suis préoccupé par les effets de quitter cette course pendant de longues périodes de temps, disons, toute la journée ou la nuit. Le squelette de code de base est la suivante:

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

(La demi-seconde « sommeil » est pour que le client ne pas marteler le serveur si les mises à jour reviennent au client rapidement -. Qu'ils sont en général)

Après avoir quitté cette course du jour au lendemain, il a tendance à faire ramper Firefox. J'avais pensé que cela pourrait être en partie causée par une grande profondeur de la pile depuis que je suis essentiellement écrit une fonction infiniment récursive. Cependant, si j'utilise Firebug et jette un point d'arrêt dans fetch, il semble que ce n'est pas le cas. La pile que Firebug me montre est seulement environ 4 ou 5 cadres en profondeur, même après une heure.

L'une des solutions que je songe à me change ma fonction récursive à un processus itératif, mais je ne peux pas comprendre comment j'insérer le délai entre les requêtes Ajax sans tourner . Je l'ai regardé le , mais je ne peux pas tout à fait wrap ma tête autour d'elle, de déterminer si c'est ce que je dois ici.

est la meilleure solution juste pour faire un rafraîchissement dur sur la page périodiquement, par exemple, une fois toutes les heures? Y at-il un meilleur / plus maigre modèle de conception à long sondage qui ne mettra pas mal sur le navigateur, même après l'exécution de 8 ou 12 heures? Ou devrais-je simplement ignorer la longue interrogation tout à fait et utiliser un autre modèle « mise à jour constante » depuis que je sais généralement à quelle fréquence le serveur aura une réponse pour moi?

Était-ce utile?

La solution

Il est également possible que c'est Firebug. Vous console.logging choses, ce qui signifie que vous avez probablement un onglet moniteur de réseau ouvert, etc, ce qui signifie que chaque demande est stockée dans la mémoire.

Essayez de le désactiver, voir si cela aide.

Autres conseils

La profondeur de la pile de 4-5 est correcte. setTimeout et $.ajax sont des appels asynchrones, qui reviennent immédiatement. Le rappel est appelé plus tard par le navigateur avec une pile d'appel vide. Puisque vous ne pouvez pas mettre en œuvre à long polling de manière synchrone, vous devez utiliser cette approche récursive. Il n'y a pas moyen de le rendre itérative.

Je soupçonne que la raison de ce ralentissement est que votre code a une fuite de mémoire. La fuite pourrait être soit en $.ajax par jQuery (très peu probable) ou dans votre appel processResults.

Il est une mauvaise idée d'appeler fetch() à l'intérieur de la méthode elle-même. Récursivité est mieux utilisé quand vous vous attendez à un certain moment la méthode atteindra fin et les résultats commencera à envoyer à l'appelant. La chose est, lorsque vous appelez la méthode récursive il garde la méthode de l'appelant ouvert et en utilisant la mémoire. Si vous êtes seulement 3-4 cadres en profondeur, il est parce que jQuery ou le navigateur sont en quelque sorte « fixer » ce que vous avez fait.

Dernières versions de soutien jquery long vote par défaut. De cette façon, vous pouvez être sûr que yhou ne sont pas deppending sur l'intelligence du navigateur pour traiter votre appel récursif infini. Lorsque vous appelez la méthode $.ajax() vous pouvez utiliser le code ci-dessous pour faire un long sondage combiné avec un coffre-fort attente de 500 millisecondes avant un nouvel appel.

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 cette façon, vous pouvez être sûr que l'appel $.ajax() est fermé avant que la suivante commence. Ceci peut être prouvé par l'ajout d'un simple console.log() au préalable et un autre après votre appel $.ajax().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top