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

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

本文介绍了永远不会解决的承诺导致内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有承诺。我创建它以在需要时取消AJAX请求。但由于我不需要取消那个AJAX,我从来没有解决它并且AJAX成功完成。



一个简化的片段:

  var defer = $ q.defer(); 
$ http({url:'example.com/some/api',timeout:defer.promise})。success(function(data){
//做点什么
});

//永远不要defer.resolve()因为我不需要取消那个ajax。请求后,这个承诺会发生什么?

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

解决方案

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



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

  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个承诺,然后只需保持在那里,整个



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

  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){//循环闭包
$ d.promise.then(function(){
console.log($ d);
});
}) ($ d);
}
},10);


所以在初始分配之后 - 看起来它也能够处理它:)



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





简而言之 - 至少在现代浏览器中 - 只要你不用担心未解决的承诺没有外部引用


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.

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?

解决方案

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

From the other side, if we look at the $q source code

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.

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

这篇关于永远不会解决的承诺导致内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 12:14