質問: createHoge, createFuga, execPiyo の三つメソッドがあります。 * createHoge, createFuga はとても大きなデータを生成する関数で、データを生成したらコールバックを呼び出すものです * execPiyo は、createHoge, createFuga で生成したデータを処理する関数で、データ処理が完了したらコールバックを呼び出すものです。 ``` createHoge(function(hoge) { createFuga(function(fuga) { execPiyo(hoge, fuga, function() { console.log("1piyo done."); // この時点で hoge, fuga を破棄したい createHoge(function(hoge) { createFuga(function(fuga) { execPiyo(hoge, fuga, function() { console.log("2piyo done."); }); }); }); }); }); }); ``` このようなコールバック呼び出しの連鎖で実行できるものとします。で、連続して execPiyo を何回も実行したい時にcreateHoge, createFugaで生成したhoge, fuga をメモリから解放できずに困っています。 RxJSやPromiseやgeneratorを使ってcreateHoge, createFuga, execPiyoの実行を複数回書いてみたんですが、どのやり方でもメモリを食いすぎて途中で落ちてしまいます。 補足: createHoge, createFuga, execPiyo の一連の処理は一回実行するだけなら問題ないんですが、複数回実行したいけど callback のチェインを続けると途中でメモリが足りなくなります。 何か解決方法はありますか?
回答: Hibiya Ryutoさんの書かれた最初のコードで言いますと、プログラム終了まで参照を保持し続けているのは`hoge`や`fuga`の他、`buffer`, `a`, `b`も同様です。 この参照を切るために、強いて形をなるべく変えずに修正すると次のようなコードになります(アプローチとしてはeripongさんの示されている回答と同じです)。 ``` function createHoge(callback) { var buffer = [new ArrayBuffer(10000000)]; callback(buffer); } function createFuga(callback) { var buffer = [new ArrayBuffer(10000000)]; callback(buffer); } function execPiyo(a, b, callback) { callback(); } function foo(i, n) { createHoge(function(hoge) { createFuga(function(fuga) { execPiyo(hoge, fuga, function() { console.log(i + "piyo done."); // この時点で buffer[0] を破棄したい hoge[0] = null; fuga[0] = null; if (n < i) return; foo(i + 1, n); }); }); }); } foo(0, 1000); ``` `buffer`を要素数1の配列とし、この配列の第1要素に本来渡したいオブジェクト(大容量オブジェクト)をセットします。 この配列を引数として渡せば、呼び出し先で大容量オブジェクトの参照を切ることができます。