4

我使用 jQuery Ajax 和 setTimeout() 每 x 秒获取一次新数据,这会导致内存泄漏。每次 Ajax 调用时,浏览器内存都会不断增加,直到浏览器崩溃。

$(document).ready(wp.state.init);

wp.state = {

    data: {},

    init: function () {
        $.PubSub('state:refresh').subscribe(function () {
            window.setTimeout(function () {
                wp.state.refresh();
            }, 1000);
        });

        this.refresh();
    },

    refresh: function () {

        $.ajax({
            url: 'http://url_here/',
            cache: false,
            dataType: "json",
            success: function (data) {
                wp.state.data = data;
                $.PubSub('state:refresh').publish();
            }
        });
    }
}

更新(基于@dez 答案)

wp.state = {

    data: {},

    init: function () {
        $.PubSub('state:refresh').subscribe(function () {
            window.setTimeout(wp.state.refresh, 1000);
        });

        this.getState();
    },

    refresh: function () {
        wp.state.getState();
    },

    onSuccess: function (data) {
        wp.state.data = data;
        $.PubSub('state:refresh').publish();
    },

    getState: function () {

        $.ajax({
            url: 'http://url_here/',
            cache: false,
            dataType: "json",
            success: this.onSuccess
        });
    }
}

笔记:

  • Publisher/Subscriber ( $.PubSub ) 实现采用此处的形式。在实施 PubSub 之前也发生了 Mem 泄漏,因此它显然不相关。
  • 使用setTimeout代替setInterval以便仅在旧的 Ajax 调用成功后执行新的 Ajax 调用。
  • 当然还有其他函数可以监听' state:refresh '并使用wp.state.data中的数据
4

1 回答 1

1

我可以在这里看到几个问题,其中一些可能会导致您的内存泄漏。

首先,第一行:

$(document).ready(wp.state.init);

这不会init在正确的范围内执行,因此该行的值this将是未定义的:

this.refresh();

你应该这样做:

$(document).ready(function(){wp.state.init();});

或修改你this.refresh()的明确wp.state.refresh()

我认为可能导致泄漏的位是......

每次$.ajax调用时,refresh都会创建一个新函数来处理成功回调。您应该将回调定义为wp.state对象上的另一个函数,并以与当前传递给方法success的方式相同的方式传递它。wp.state.initready()

同样,每次您调用window.setTimeout订阅到您的 PubSub 的函数时,您也在创建一个函数来处理该回调。您应该在此处执行相同操作并将其提取到wp.state.

于 2012-04-22T23:20:03.553 回答