不会解决延迟造成的内存泄漏吗? [英] Will not resolving a deferred create memory leaks?

查看:81
本文介绍了不会解决延迟造成的内存泄漏吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设以下代码:

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(),这会导致内存泄漏,因为我在回调中保留了引用?

  1. If I never end up calling resolve() or fail(), will this cause memory leaks, since I keep references in the callbacks?

如果我呼叫一个,但不呼叫另一个,是否会垃圾回收?因此,如果我呼叫fail(),jquery是否会摆脱done()?

If I call one, but not the other, will the other be garbage collected? So if I call fail(), will jquery get rid of done()?

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

I might be thinking wrong entirely, but would like some clarification. The closest I have found thus far was this Shall I always invoke either JQuery Deferred.resolve or Deferred.reject?. But the use case is a bit different, since in that example the user has never defined a callback for fail().

我也遇到了这个问题,可以取消jQuery延迟吗?我没有试图取消deferred.

I also came across this, Can jQuery deferreds be cancelled?, however I am not trying to cancel a deferred.

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

I understand that this is not best practice, but for the purpose of the question I am still curious if it would cause memory problems.

谢谢

推荐答案

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

If I never end up calling resolve() or fail(), will this cause memory leaks, since I keep references in the callbacks?

如果deferred变量本身无法再由您的任何代码访问(这也意味着没有其他应许取决于此),那么即使从未解决或拒绝它,它也有资格进行垃圾回收. .如果您想进一步了解可达"的含义,那么最好显示您所关注的实际代码.

If the deferred variable itself is no longer reachable by any of your code (which also means there are no other promises depending upon this one), then it will be eligible for garbage collection even though it was never resolved or rejected. If you want more specifics on what "reachable" means, then it would be best for you to show your actual code that you're concerned about.

另一方面,如果您仍在某个地方使用deferred变量,或者仍然可以实现的其他承诺取决于此承诺(这意味着这些承诺引用了该承诺),则它不会不管延迟的对象是否已解析,它仍然是活动的并且不能被垃圾回收.

If, on the other hand, you're still holding onto the deferred variable somewhere or other promises that are still reachable are depending upon this promise (which means those promises have a reference to this one), then it doesn't matter whether the deferred object has been resolved or not, it will still be alive and cannot be garbage collected.

当涉及垃圾回收时,承诺只是普通的Javascript对象,因此它们遵循与普通对象相同的所有垃圾回收规则.

Promises are just ordinary Javascript objects when it comes to garbage collection so they follow all the same garbage collection rules as ordinary objects.

如果我呼叫一个,但不呼叫另一个,是否会垃圾回收? 因此,如果我调用fail(),jQuery会摆脱done().

If I call one, but not the other, will the other be garbage collected? So if I call fail(), will jquery get rid of done().

代码本身不会收集垃圾.收集垃圾的是变量和对象的内容.因此,在显示的代码中,垃圾收集的主题是deferred变量(变量指向的Promise对象)的内容.而且,就像我在上面说的那样,您是否已解决,拒绝还是两者都不重要.重要的是该对象是否仍然可以通过您的代码访问.如果任何代码仍然可以到达deferred变量,或者任何其他代码或promise仍然可以引用该promise.

Code itself doesn't get garbage collected. It's the contents of variables and objects that gets garbage collected. So, in the code you show, it's the contents of the deferred variable (the promise object that variable points to) that is the subject of garbage collection. And, as I said above it makes no difference whether you've resolved, rejected or neither. What matters is if the object is still reachable by your code or not. If any code can still reach the deferred variable or if any other code or promises has a still reachable reference to this promise.

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

As an example, if I have this top level code in my page:

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

deferred变量仍然可以访问并且仍然有效,因此无法对其进行指向的Deferred对象进行垃圾收集.

The deferred variable is still reachable and still alive so the Deferred object that it points to cannot be garbage collected.

或者,如果我有这个:

<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,因此它变得不可访问.届时,它就有资格进行垃圾收集了.

Then, as soon as the ajax call completes and the .done() handler is called, then there is no longer any code that can reach that instance of the p variable because the ajax operation is done so it will release its reference to the promise and thus it can't trigger any more promise callbacks itself. And, it has gone out of scope of the click handler callback function and there are no live event handlers that could still access p so it has become unreachable. At that point, it would be eligible for garbage collection.

这篇关于不会解决延迟造成的内存泄漏吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆