0

Apache ベースの Web アプリケーションがあります。php、js、およびjquery。すべて正常に動作します。

クライアント側には、JS/jquery の小さなライブラリがあり、いくつかの一般的なリスト処理メソッドを提供しています。以前は、コールバックを使用して、これらのメソッドの動作がわずかに異なるいくつかの問題を処理していました。そうすれば、リスト処理、ダイアログ処理などのメソッドをアプリケーションのさまざまな部分で再利用できます。ただし、最近、ライブラリにステップインするときに処理しなければならなかったコールバックの数が増えたため、再設計を試みています。

すべてのコールバックを関数の引数として指定する代わりに、ライブラリに中央のカタログ オブジェクトを作成しました。アプリケーションの各モジュールは、初期化時にコールバックの独自のバリアントをそのカタログに登録します。実行時に、メソッドは、引数のリストで指定されていることを期待するのではなく、そのカタログで必要なコールバックを検索します。これにより、かなり多くのことがクリーンアップされます。

ただし、まだ取り除けないことが 1 つあります。それは、メソッドがカタログ内の必要なコールバックを検索するために使用する 1 つの引数 (コンテキストと呼びます。モードは別の用語である可能性があります) が必要です。このコンテキストは、すべてのメソッドに渡す必要があります。確かに、あらゆる場所でさまざまなコールバックが指定されているよりはましですが、最後のコールバックを取り除くことができるかどうかは疑問です。しかし、メソッドの引数ではない場合、どこでそのコンテキストを指定すればよいでしょうか? 私はJSとjqueryにかなり慣れていないので、これに対するアプローチを見つけることができませんでした. どうやら私はグローバル変数を使用したくありません。率直に言って、すべてのイベントハンドラーと外部影響メソッドのために、異なるコンテキストで同時に呼び出される可能性があるため、コンテキストを単一の変数に単純に格納できるとは思えません。時間、または少なくともインターリーブ。したがって、関数スタックに近いものが必要だと思います。たぶん、コンテキストオブジェクトをスタックにプッシュして、知る必要があるライブラリのレイヤー内からそれを読み取ることができますか? ライブラリを再び離れると、オブジェクトは削除されます。確かに他のアプローチも存在します。

ここに非常に多くの経験豊富なコーダーが、初心者に短いヒント、アイデアにつながる出発点、これを実装する方法を確実に与えることができます. そのようなことは「通常」どのように行われますか?


arguments.callee.callerヒエラルキーを調べながら、しばらく回ってみました。呼び出し元の関数内にプロトタイプ メンバーを設定できるのではないかと考えた場合、実行がさらに下に進むと、そのようなプロパティを保持している呼び出し元が見つかるまでコール スタックを上方向にトラバースし、その値をコンテキストとして使用できます。しかし、進行中の議論では、1.)arguments.callee減価償却されているように見えること、および 2.) 非常に高価であるように見えることもわかりました。だから、それはいけません。

Function.caller の代替案についても読みました(減価償却されておらず、はるかに効率的であるように見えますが、今までそのトレイルを探索できませんでした...


現在書かれているように、コンテキスト/モードを下に渡すことは、関数呼び出しで追加の引数を指定するだけで機能します。カタログを参照するときにキーとして使用される一意の文字列を保持します。したがって、次のようなものです(コピーされていませんが、基本的な例として書かれています):

<!-- callbacks -->
callback_inner_task_base:function(arg1,arg2){
  // do something with args
}
callback_inner_task_spec:function(arg1,arg2){
  // do something with args
}

<!-- catalog -->
Catalog.Callback:function(context,slot){
  // some plausibility checks...
  return Catalog[context][slot];
}
Catalog.base.slot=callback_inner_task_base;
Catalog.spec.slot=callback_inner_task_spec;

<!-- callee -->
do_something:function(arg1,arg2,context){
  ...
  // callback as taken from the catalog
  Catalog.Callback(callback,'inner_task')(arg1,arg2);
  ...
}

<!-- caller -->
init:function(...){
  ...
  do_something('thing-1',thing-2','base');
  do_something('thing-1',thing-2','spec');
  ...
}
4

1 に答える 1