webentwicklung-frage-antwort-db.com.de

Verursacht ein nie gelöstes Versprechen einen Speicherverlust?

Ich habe ein Promise. Ich habe es erstellt, um eine AJAX Anfrage zu stornieren, falls erforderlich. Aber da ich dieses AJAX nicht stornieren muss, habe ich es nie gelöst und AJAX abgeschlossen erfolgreich.

Ein vereinfachtes Snippet:

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?

Verursachen solche nie gelösten Versprechungen Speicherlecks? Haben Sie Ratschläge zum Verwalten des Promise Lebenszyklus?

83
Umut Benzer

Nun, ich gehe davon aus, dass Sie keinen expliziten Verweis darauf behalten, da dies die Zuweisung zwingen würde.

Der einfachste Test, den ich mir vorstellen kann, besteht darin, viele Versprechen zuzuweisen und sie nicht zu lösen:

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

Und dann den Haufen selbst beobachten. Wie wir in den Chrome Profiling Tools sehen können, sammelt dies den erforderlichen Speicher, um 100 Versprechen zuzuweisen, und bleibt dann nur bei weniger als 15 Megabyte für die gesamte Seite JSFIddle)

enter image description here

Von der anderen Seite, wenn wir uns die $q Quellcode

Wir können sehen, dass es keinen Bezug von einem globalen Punkt zu einem bestimmten Versprechen gibt, sondern nur von einem Versprechen zu seinen Rückrufen. Der Code ist sehr gut lesbar und klar. Mal sehen, was passiert, wenn Sie jedoch einen Verweis vom Rückruf auf das Versprechen haben.

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

Also nach der anfänglichen Zuweisung - es scheint, als könnte es auch damit umgehen :)

Wir können auch einige interessante Muster von GC sehen, wenn wir sein letztes Beispiel noch ein paar Minuten laufen lassen. Wir können sehen, dass es eine Weile dauert - aber es ist möglich, die Rückrufe zu bereinigen.

enter image description here

Kurz gesagt - zumindest in modernen Browsern - müssen Sie sich nicht um ungelöste Versprechungen kümmern, solange Sie keine externen Verweise auf diese haben

141