コールバック関数はいくつかのパラメーターを受け入れることができますが、関数を呼び出すときに明示的に宣言されていません。
これは実際どのように機能しますか?関数をパラメーターとして別の関数に渡し、そこにパラメーターを暗黙的に含めることを可能にしているのは何ですか?
例えば:
Javascript
$.get('somefile.php', {func : 'getUserNames'}).done(function(data){
if(data)
console.log(data); // '{"0" : "billy", "1" : "bobby"}'
// This is a js ajax call to a php file.
// How exactly am I retrieving "data" ?
}, 'json');
C#
private void BeginReadingData(){
NetworkStream stream = tcpClient.GetStream();
stream.BeginRead(buffer, 0, bufferSize, MyCallBack, tcpClient);
}
private void MyCallBack(IAsyncResult ar){
// Now I can operate on 'ar'
// why and how?
}
これは、プロセスを説明したり正しく説明したりする方法ではなく、使用方法を理解しているものです。
一部のパラメーターを受け入れるコールバック関数を何と呼びますが、それらは関数を呼び出すときに明示的に宣言されていませんか?
よく分かりません。場合によっては、オブジェクトのメソッドは、オブジェクト自体を暗黙的なパラメーターとして持つと見なされる場合があります。
しかし、あなたの例のような暗黙のパラメーターを持つ関数呼び出しはありません。コールバックでは、関数を呼び出した結果を渡すのではなく、関数自体を渡します。
stream.BeginRead(buffer, 0, bufferSize,
MyCallBack, /* <- Not a function call, just a reference to a function. */
tcpClient);
コールバックに指定した関数。これらの場合、$.get
およびstream.BeginRead
は、指定したコールバック関数を呼び出し、必要なパラメーターを明示的に指定します。
したがって、ここで欠落しているのは、stream.BeginRead
の定義が次のようなものであることです。
public virtual ISyncResult BeginRead(
byte[] buffer,
int offset,
int count,
AsyncCallback callback,
Object state
) {
/* stuff */
callback(ar); /* <-- called with explicit parameter */
/* more stuff */
}
一部のパラメーターを受け入れるコールバック関数を何と呼びますが、それらは関数を呼び出すときに明示的に宣言されていませんか?
あなたが何を話しているのか分かりません。
function(data)
explicitlyは、匿名関数に対してdata
という名前のパラメーターを宣言します。
private void MyCallBack(IAsyncResult ar)
explicitlyar
という名前の関数に対して、IAsyncResult
という名前のパラメーターを型MyCallback
で宣言します。
それらは両方ともその識別子を関数の本体で利用可能にし、コンパイラ/インタープリタはその識別子解決を「この関数の最初の引数にアクセスする」に変換することを知っています。
C#では、コールバックは単なるデリゲートです。デリゲートはオブジェクト内でコールバックメソッドをラップし、そのオブジェクトはパラメーターとして渡されます。したがって、コールバック関数を渡すときは常に、イベントハンドラーを例に挙げると、そのイベントハンドラーはデリゲートオブジェクトにラップされています。これで、適切な呼び出し時刻になると、対応する要素(例では 'NetworkStream'オブジェクト)がコールバックが登録されているかどうかを確認します。見つかった場合(あなたの場合-'MyCallback'が登録されています)、登録されたコールバックを呼び出します。
JavaScriptでは、設計上、メソッドはオブジェクトそのものにすぎません。したがって、コールバック関数を渡すときは常に、オブジェクトを渡します。 JavaScriptはコンパイルするので、渡すコールバックの署名はチェックしません。適切な署名がある場合(たとえば、適切な数のパラメーターがある場合)、コールバックはすべての値を受け取ります。署名が一致しない場合、コールバックは結果の値を見逃します。