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
        });
    }
}

ノート:

  • パブリッシャー/サブスクライバー($ .PubSub)の実装はここから取得されます。Memリークは、PubSubを実装する前にも発生したため、明らかに関連性はありません。
  • 古いものが成功した後にのみ新しいAjax呼び出しを実行するために、 setIntervalの代わりにsetTimeoutが使用されます。
  • もちろん、「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.initありready()ます。

同様に、PubSub にサブスクライブした関数を呼び出すたびwindow.setTimeoutに、そのコールバックを処理する関数も作成しています。ここで同じことを行い、それを関数 on に抽出する必要がありますwp.state

于 2012-04-22T23:20:03.553 に答える