web-dev-qa-db-ja.com

フックとコールバックの違いは何ですか?

いくつかのテキスト、特にデリゲートに関するiOSドキュメントを読むことにより、すべてのプロトコルメソッドが呼び出されますhookカスタムデリゲートオブジェクトが実装する必要があります。しかし、他のいくつかの本では、これらの名前をhookcallbackとしていますが、それらの違いは何ですか?それらは単に異なる名前ですが、同じメカニズムですか? Obj-Cに加えて、Cなどの他のプログラミング言語もhookを取得しました。これは、Obj-Cと同じ状況ですか?

30
coanor

ここでの用語は少しあいまいです。一般に、2つは同様の結果を達成しようとします。

一般に、コールバックは、処理フローの適切な時間に呼び出されるようにAPIに登録する関数(またはデリゲート)です(たとえば、処理が特定の段階にあることを通知するため) )

hookは、伝統的に、APIへの呼び出しを変更する目的に役立つもう少し一般的なものを意味します(たとえば、渡されたパラメーターの変更、呼び出された関数の監視)。この意味では、通常、Javaなどの高級言語で実現できるレベルよりもはるかに低いレベルです。

iOSのコンテキストでは、単語hookは、上記のcallbackとまったく同じことを意味します

28
Attila

2つの用語は非常に似ており、同じ意味で使用されることもあります。フックはライブラリのオプションであり、ユーザーコードは関数をリンクしてライブラリの動作を変更できます。ライブラリ関数は、ユーザーコードと同時に実行する必要はありません。デストラクタのように。

コールバックは、ユーザーコードがライブラリ呼び出し(通常はI/O呼び出しまたはGUI呼び出し)を開始する特定のタイプのフックであり、カーネルまたはGUIサブシステムに制御を渡します。次に、制御プロセスは、割り込みまたはシグナルでユーザーコードを「コールバック」し、ユーザーコードがハンドラーを提供できるようにします。

歴史的に、割り込みハンドラーに使用されるフックとGUIイベントハンドラーに使用されるコールバックを見てきました。また、ルーチンを静的にリンクするときにフックを使用し、動的コードでコールバックを使用することもわかります。

12
starbolin

Javascriptの答えでチャイムを鳴らしましょう。 Javascriptでは、コールバックフックおよびeventsはすべて使用されます。この順序で、それらはそれぞれ他よりも高いレベルの概念です。

残念ながら、それらはしばしば不適切に使用され、混乱を招きます。

コールバック

制御フローの観点からは、callbackは関数であり、通常は引数として指定され、関数から戻る前に実行します。

これは通常、I/Oを待機する必要がある非同期の状況で使用されます(HTTPリクエスト、ファイルの読み取り、データベースクエリなど)。同期whileループで待機したくないので、その間に他の関数を実行できます。

データを取得したら、(永続的に)制御を放棄し、結果を使用してコールバックを呼び出します。

_function myFunc(someArg, callback) {
    // ...
    callback(error, result);
}
_

コールバック関数はまだ実行されていないコードである可能性があり、呼び出しスタックで関数の上に何があるかわからないため、通常、エラーをスローする代わりに、エラーを引数としてコールバックに渡します。 error-firstおよびresult-firstコールバック規則があります。

Javascriptの世界ではほとんどのコールバックが Promises に置き換えられており、ES2017 +以降、ネイティブで _async/await_ を使用して、コールバックが豊富なスパゲッティコードを取り除き、非同期にすることができます。制御フローは同期していたように見えます。

特別なカスケード制御フローでは、関数の途中でコールバックを実行する場合があります。 in Koa(Webサーバー)ミドルウェアnext()を実行すると、スタック内の他のすべてのミドルウェアが実行された後に返されます。

フック

フックは実際には明確に定義された用語ではありませんが、Javascriptの実践では、クライアント(API /ライブラリユーザー、子クラスなど)が制御フローの明確に定義されたポイントでオプションのアクションを実行するようにするときにフックを提供します。

したがって、フックは、特定のポイントで呼び出す関数(引数やクラスメソッドなど)である可能性があります。データベースの更新中:

_data = beforeUpdate(data);

// ...update

afterUpdate(result);
_

通常、ポイントは次のとおりです。

  • フックはオプションにすることができます
  • フックは通常待機します。つまり、一部のデータを変更するためにフックがあります。
  • フックごとに呼び出される関数は最大で1つです(イベントとは異なります)

イベント

Javascriptでは、イベントは特定の時点で送信され、クライアントはそれらをサブスクライブできます。イベントが発生したときに呼び出される関数は、listeners-またはさらに混乱する場合はcallbacks。私はこのために「コールバック」という用語を避け、代わりに「リスナー」という用語を使用することを好みます。

これも一般的なOOPパターンです。

フロントエンドにはイベント用の DOMインターフェイス があり、node.jsには EventEmitter インターフェイスがあります。洗練された非同期バージョンは ReactiveX に実装されています。

イベントのプロパティ:

  • 同じイベントに対してサブスクライブされた(実行される)複数のリスナー/コールバックが存在する場合があります。
  • 通常、コールバックは受信せず、一部のイベント情報のみを受信し、同期的に実行されます
  • 一般的に、フックとは異なり、イベントエミッターの制御フロー内のデータを変更するためのものではありません。エミッターは「聞いている人がいれば」気にしません。イベントデータを使用してリスナーを呼び出すだけで、すぐに続行されます。

例:イベントは、データストリームが開始または終了したとき、ユーザーがボタンをクリックしたとき、または入力フィールドを変更したときに発生します。

5
gombosg

すでに2つのすばらしい答えがありますが、「フック」と「コールバック」という用語は同じであり、同じ意味で使用できるという証拠をもう1つ入れたかったのです:FreeRTOSは「フック」という用語を支持しますが、「コールバック」を同等の用語として認識します。

アイドルタスクは、オプションで、アプリケーションで定義されたフック(またはコールバック)関数(アイドルフック)を呼び出すことができます。

ティック割り込みは、オプションで、アプリケーションで定義されたフック(またはコールバック)関数(ティックフック)を呼び出すことができます。

Heap_1.c、heap_2.c、heap_3.c、heap_4.c、およびheap_5.cによって実装されるメモリ割り当てスキームには、オプションでmalloc()障害フック(またはコールバック)pvPortMalloc()がNULLを返した場合に呼び出されるように構成できる関数。

出典: https://www.freertos.org/a00016.html

3
Gabriel Staples