javascript 从未解决的承诺会导致内存泄漏吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20068467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does never resolved promise cause memory leak?
提问by Umut Benzer
I have a Promise
. I created it to cancel an AJAX request if needed. But since I don't need to cancel that AJAX, I've never resolved it and AJAX completed successfully.
我有一个Promise
. 我创建它是为了在需要时取消 AJAX 请求。但是由于我不需要取消那个 AJAX,所以我从来没有解决它并且 AJAX 成功完成。
A simplified 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?
Do never resolved promises like that cause memory leaks? Do you have any advice about how to manage Promise
life cycle?
从来没有解决过这样的承诺会导致内存泄漏吗?您对如何管理Promise
生命周期有什么建议吗?
回答by Benjamin Gruenbaum
Well, I'm assuming you don't keep an explicit reference to it since that would force it to stay allocated.
好吧,我假设您没有明确引用它,因为这会迫使它保持分配状态。
The simplest test I could think of is actually allocating a lot of promises and not resolving them:
我能想到的最简单的测试实际上是分配了很多承诺而不是解决它们:
var $q = angular.injector(["ng"]).get("$q");
setInterval(function () {
for (var i = 0; i < 100; i++) {
var $d = $q.defer();
$d.promise;
}
}, 10);
And then watching the heap itself. As we can see in the Chrome profiling tools, this accumulates the needed memory to allocate a 100 promises and then just "stays there" at less than 15 megabyes for the whole JSFIddle page
然后观察堆本身。正如我们在 Chrome 分析工具中看到的那样,这积累了分配 100 个 promise 所需的内存,然后在整个JSFIddle 页面上“停留在那里”不到 15 兆字节
From the other side, if we look at the $q
source code
另一方面,如果我们看$q
源代码
We can see that there is no reference from a global point to any particular promise but only from a promise to its callbacks. The code is very readable and clear. Let's see what if you do however have a reference from the callback to the promise.
我们可以看到,没有从全局点到任何特定承诺的引用,而只有从承诺到其回调的引用。代码非常可读和清晰。让我们看看如果你确实有从回调到承诺的引用。
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);
So after the initial allocation - it seems like it's able to handle that as well :)
所以在初始分配之后 - 它似乎也能够处理它:)
We can also see some interesting patterns of GC if we let his last example run for a few more minutes. We can see that it takes a while - but it's able to clean the callbacks.
如果我们让他的最后一个例子再运行几分钟,我们还可以看到一些有趣的 GC 模式。我们可以看到这需要一段时间 - 但它能够清理回调。
In short - at least in modern browsers - you don't have to worry about unresolved promises as long as you don't have external references to them
简而言之 - 至少在现代浏览器中 - 只要您没有对它们的外部引用,您就不必担心未解决的承诺