【问题标题】:Will not resolving a deferred create memory leaks?不会解决延迟创建内存泄漏?
【发布时间】:2015-06-27 17:25:44
【问题描述】:

假设如下代码:

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()吗?

我可能完全想错了,但想澄清一下。到目前为止,我发现的最接近的是Shall I always invoke either JQuery Deferred.resolve or Deferred.reject?。但用例有点不同,因为在该示例中,用户从未为 fail() 定义回调。

我也遇到过这个,Can jQuery deferreds be cancelled?,但我并不想取消deferred。

我知道这不是最佳做法,但出于这个问题的目的,我仍然很好奇它是否会导致内存问题。

谢谢,

【问题讨论】:

    标签: jquery deferred


    【解决方案1】:

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

    如果您的任何代码都无法访问 deferred 变量本身(这也意味着没有其他取决于此的承诺),那么即使它从未被解决或拒绝,它也将有资格进行垃圾收集.如果您想更详细地了解“可达”的含义,那么最好展示您关心的实际代码。

    另一方面,如果您仍然在某处持有deferred 变量,或者其他仍可访问的承诺取决于此承诺(这意味着这些承诺有对这个的引用),那么它不会'不管延迟对象是否被解析,它仍然是活动的,不能被垃圾回收。

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

    如果我调用一个,而不调用另一个,另一个会被垃圾回收吗? 所以如果我调用fail(),jquery会摆脱done()吗?

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


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

    <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,因此它变得无法访问。届时,它将有资格进行垃圾回收。

    【讨论】:

    • 感谢您的详细解答!
    猜你喜欢
    • 2011-03-09
    • 1970-01-01
    • 2013-09-02
    • 2015-06-28
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多