web-dev-qa-db-fra.com

Une promesse jamais résolue provoque-t-elle une fuite de mémoire?

J'ai un Promise. Je l'ai créé pour annuler une demande AJAX si nécessaire. Mais comme je n'ai pas besoin d'annuler cet AJAX, je ne l'ai jamais résolu et AJAX terminé) avec succès.

Un extrait simplifié:

var defer = $q.defer();
$http({url: 'example.com/some/api', timeout: defer.promise}).success(function(data) {
    // do something
});

// Never defer.resolve() because I don't need to cancel that ajax. What happens to this promise after request?

Des promesses jamais résolues comme celle-là ne provoquent-elles des fuites de mémoire? Avez-vous des conseils sur la façon de gérer le cycle de vie de Promise?

83
Umut Benzer

Eh bien, je suppose que vous ne conservez pas de référence explicite, car cela l'obligerait à rester alloué.

Le test le plus simple auquel je pouvais penser est en fait d'allouer beaucoup de promesses et non de les résoudre:

var $q = angular.injector(["ng"]).get("$q");
setInterval(function () {
    for (var i = 0; i < 100; i++) {
        var $d = $q.defer();
        $d.promise;
    }
}, 10);

Et puis regarder le tas lui-même. Comme nous pouvons le voir dans les outils de profilage Chrome, cela accumule la mémoire nécessaire pour allouer 100 promesses, puis "reste là" à moins de 15 mégaoctets pour l'ensemble page JSFIddle

enter image description here

De l'autre côté, si nous regardons le $q code source

Nous pouvons voir qu'il n'y a aucune référence d'un point global à une promesse particulière mais seulement d'une promesse à ses rappels. Le code est très lisible et clair. Voyons voir si vous avez cependant une référence du rappel à la promesse.

var $q = angular.injector(["ng"]).get("$q");
console.log($q);
setInterval(function () {
    for (var i = 0; i < 10; i++) {
        var $d = $q.defer();
        (function ($d) { // loop closure thing
            $d.promise.then(function () {
                console.log($d);
            });
        })($d);
    }
}, 10);

enter image description here

Donc, après l'allocation initiale - il semble qu'il soit également capable de gérer cela :)

Nous pouvons également voir quelques modèles intéressants de GC si nous laissons son dernier exemple fonctionner pendant quelques minutes de plus. Nous pouvons voir que cela prend un certain temps - mais il est capable de nettoyer les rappels.

enter image description here

En bref - au moins dans les navigateurs modernes - vous n'avez pas à vous soucier des promesses non résolues tant que vous n'avez pas de références externes à celles-ci

141
Benjamin Gruenbaum