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

Lev*_*zov 6 jquery deferred

假设以下代码:

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...
});
Run Code Online (Sandbox Code Playgroud)
  1. 如果我从不结束调用,resolve()或者fail()这会导致内存泄漏,因为我在回调中保留引用?

  2. 如果我打电话给一个,而不打另一个,那么另一个会被垃圾收集吗?所以,如果我打电话fail(),jquery将摆脱done()

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

我也遇到过这个问题,jQuery deferreds会被取消吗?,但我不是想取消一个deferred.

我知道这不是最佳做法,但出于问题的目的,我仍然很好奇它是否会引起记忆问题.

谢谢,

jfr*_*d00 8

如果我永远不会最终调用resolve()或fail(),这会导致内存泄漏,因为我在回调中保留了引用吗?

如果deferred您的任何代码都无法访问变量本身(这也意味着根据此代码没有其他承诺),那么即使它从未被解析或拒绝,它也有资格进行垃圾收集.如果您想了解"可达"含义的更多细节,那么最好显示您关注的实际代码.

另一方面,如果你仍然在deferred某个地方持有变量或者仍然可以到达的其他承诺取决于这个承诺(这意味着那些承诺引用了这个承诺),那么延迟是否延迟并不重要对象已经解决与否,它仍然存在并且不能被垃圾收集.

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

如果我打电话给一个,而不打另一个,那么另一个会被垃圾收集吗?因此,如果我调用fail(),jquery将摆脱done().

代码本身不会收集垃圾.这是收集垃圾的变量和对象的内容.因此,在您显示的代码中,它是deferred变量(变量指向的promise对象)的内容,它是垃圾收集的主题.而且,正如我上面所说,无论你是否已经解决,拒绝或两者都没有.重要的是,如果您的代码仍然可以访问该对象.如果任何代码仍然可以到达deferred变量,或者任何其他代码或promises仍然可以访问此承诺.


例如,如果我在页面中有这个顶级代码:

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

deferred变量仍然可以访问并且仍然存活,因此它指向的Deferred对象不能被垃圾回收.


或者,如果我有这个:

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

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