不会解决延迟创建内存泄漏吗



假设以下代码:

var deferred = $.Deferred();
deferred.done(function(){
// do something with events, references to dom, etc...
});
deferred.fail(function(){
// do something with events, references to dom, etc...
});
  1. 如果我从未调用过resolve()fail(),这会导致内存泄漏吗,因为我在回调中保留了引用?

  2. 如果我给其中一个打电话,但不给另一个打,另一个会被垃圾收集吗?那么,如果我调用fail(),jquery会去掉done()吗?

我可能完全错了,但我想澄清一下。到目前为止,我发现的最接近的是这样的:我应该总是调用JQuery Deferred.resolve或Deferred.Report吗?。但是用例有点不同,因为在该示例中,用户从未定义过fail()的回调。

我还遇到了这个问题,jQuery延期可以取消吗?,然而,我并没有试图取消deferred

我知道这不是最好的做法,但就这个问题而言,我仍然很好奇这是否会导致记忆问题。

谢谢你,

如果我从未调用resolve()或fail(),这会导致内存泄漏,因为我在回调中保留了引用?

如果deferred变量本身不再可由您的任何代码访问(这也意味着没有其他承诺依赖于此承诺),那么它将有资格进行垃圾收集,即使它从未被解析或拒绝。如果你想要更多关于"可达"的细节,那么最好展示你关心的实际代码。

另一方面,如果您仍然在某个地方保留deferred变量,或者其他仍然可以访问的promise依赖于这个promise(这意味着这些promise引用了这个promise),那么无论延迟对象是否已被解析,它都将仍然有效,不能被垃圾收集。

Promise在垃圾收集方面只是普通的Javascript对象,因此它们遵循与普通对象相同的垃圾收集规则。

如果我调用一个,而不调用另一个,那么另一个会被垃圾回收吗?所以如果我调用fail(),jquery会去掉done()吗。

代码本身不会被垃圾收集。垃圾收集的是变量和对象的内容。因此,在您显示的代码中,deferred变量(变量指向的promise对象)的内容是垃圾收集的主题。而且,正如我在上面所说的,你是否已经解决、拒绝或两者都没有区别。重要的是您的代码是否仍然可以访问对象。如果任何代码仍然可以访问deferred变量,或者如果任何其他代码或promise具有对此promise的仍然可以访问的引用。


例如,如果我的页面中有以下顶级代码:

<script>
var deferred = $.Deferred();
deferred.done(function(){
// do something with events, references to dom, etc...
});
deferred.resolve();
</script>

deferred变量仍然是可访问的并且仍然是活动的,因此它所指向的Deferred对象不能被垃圾收集。


或者,如果我有这个:

<script>
$("#submit").click(function() {
var p = $.get(myURL);
p.done(function(data) {
if (data) {
$("#msg").html(data.msg);
}
});
});
</script>

然后,一旦ajax调用完成并调用了.done()处理程序,就不再有任何代码可以访问p变量的实例,因为ajax操作已经完成,因此它将释放对promise的引用,因此它本身无法触发任何promise回调。而且,它已经超出了单击处理程序回调函数的范围,并且没有活动事件处理程序仍然可以访问p,因此它变得不可访问。到那时,它将有资格进行垃圾收集。

最新更新