永远不会解决的承诺导致内存泄漏?

时间:2013-11-19 10:03:06

标签: javascript angularjs memory-leaks promise angular-promise

我有Promise。我创建它以在需要时取消AJAX请求。但是因为我不需要取消那个AJAX,所以我从未解决它并且AJAX成功完成。

简化代码段:

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?

永远不会解决这样的承诺会导致内存泄漏吗?您对如何管理Promise生命周期有任何建议吗?

1 个答案:

答案 0 :(得分:138)

好吧,我假设你没有明确提及它,因为这会迫使它保持分配。

我能想到的最简单的测试实际上是分配了许多承诺而没有解决它们:

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

然后看着堆本身。正如我们在Chrome分析工具中看到的那样,这会积累所需的内存以分配100个承诺,然后只需“保持在那里”,整个JSFIddle page

小于15兆字节

enter image description here

另一方面,如果我们看一下$q source code

我们可以看到,从全局角度来看,没有任何特定承诺的引用,只能来自对其回调的承诺。代码非常易读且清晰。让我们看看如果你做了什么但是从回调到承诺的引用。

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

所以在初始分配之后 - 似乎它也能够处理它:)

如果我们让他的最后一个例子再运行几分钟,我们也可以看到一些有趣的GC模式。我们可以看到它需要一段时间 - 但它能够清理回调。

enter image description here

简而言之 - 至少在现代浏览器中 - 只要您没有对它们的外部引用,您就不必担心未解决的承诺