0

私はそこにあるさまざまなMV*フレームワークのパターンを調査してきましたが、今日、いくつかの問題を引き起こしているように見える奇妙なものに気づきました。

モデルのプロトタイプ。プロパティがありますcollections: []

コレクションのプロトタイプ。プロパティがありますmodels: []

コレクションが新しいモデルを取得すると、そのモデルはプッシュされますcollection.modelsが、モデル自体も、そのメンバーであるコレクションを認識するように装飾されています。つまり、コレクションインスタンスがにプッシュされmodel.collectionsます。

コレクションプロパティを持つモデルであるbeingを含むコレクションも同様です...などmodel.collections[0].models[0]

最も基本的なもの:

var A = function() {
    this.collections = [];
},
    B = function() {
        this.models = [];
        this.add = function(what) {
            what.collections.push(this);
            this.models.push(what)
        };
    };


var model = new A();
var collection = new B();

collection.add(model);

有罪判決を受けた当事者は次のとおりです:https ://github.com/lyonbros/composer.js/blob/master/composer.js#L310-313そしてさらに下にあるモデルにプッシュしています:https ://github.com/ lyonbros / composer.js / blob / master / comboser.js#L781-784

ある程度の遅延評価があると思います。必要になるまで使用されません。そのコードは、それ自体で機能します。

しかし、私はbuster.jsを介してテストを作成していて、依存しているすべてのテストが(FF)または(Chrome)sinon.spy()を生成していることに気付きました。キャプチャされたFFは、応答せずにクラッシュしていました。これは、バスターテストドライバーでこれまで遭遇したことはありません。昼休みに3.5GBのRAMを使用することさえありました。InternalError: too much recursionRangeError: Maximum call stack size exceeded

かなりの量のデバッグを行った後、参照ストレージを元に戻しましたが、突然、すべて正常に動作しました。確かに、spy()アサーションの削除も機能しましたが、それは重要ではありません。

だから、問題は-そのようなコードを持っていることは、それが受け入れられるか、ブラウザがそれをどのように解釈するか、ボトルネックは何ですか、そしてモデルが属するコレクション(おそらくコレクションコントローラとコレクションuid)へのポインタでモデルをどのように装飾するかですか何か)。

失敗するbuster.jsテストの完全な要点:https ://gist.github.com/2960549

4

2 に答える 2

2

ブラウザは気にしません。問題は、使用していたツールがオブジェクトグラフを介して循環参照チェーンをチェックできなかったことです。それらは完全に合法です、少なくともあなたがそれらを望みそしてそれらを期待するならばそれらはそうです。

オブジェクトとそのプロパティ、およびそれらのプロパティを介して直接または間接的に参照されるオブジェクトについて考える場合、そのアセンブリはグラフを構成します。周りの参照をたどり、開始した場所に戻ることができる場合、それはグラフにサイクルがあることを意味します。言語がサイクルを許可することは間違いなく良いことです。特定のシステムで適切かどうかは、関連するコード次第です。

したがって、たとえば、オブジェクトがすでにアクセスされているかどうかを確認せずにオブジェクトグラフをトラバースする再帰関数は、グラフが循環的である場合、「再帰が多すぎる」エラーを確実にトリガーします。

于 2012-06-20T19:26:24.337 に答える
1

相互に参照するオブジェクトは2つだけです(「循環参照」と呼ばれます)。

var a, b = {a: a={b: b}};
// a.b: pointer to b
// b.a: pointer to a

再帰はまったくありません。エラーが発生した場合はtoo much recursionMaximum call stack size exceeded頻繁に呼び出される関数が必要です。これは、たとえば、循環参照を気にせずにオブジェクトのクローンを作成し、プロパティを再帰しようとした場合に発生する可能性があります。コードをさらに調べる必要があります。また、エラーメッセージには(非常に長い)呼び出しスタックが含まれている必要があります。

于 2012-06-20T19:29:42.330 に答える