web-dev-qa-db-ja.com

イベントハンドラーとコールバックの違い

イベントハンドラーとコールバック関数の違いは何ですか?

60
6pack kid

一般的に、「コールバック」は検出プロセスの制御下にあります。したがって、GUIマネージャーに「このボタンが押されたときにmyactionを呼び出す」と伝え、GUIマネージャーはボタンが押されたときにアクションを呼び出します。

一方、イベントハンドラは削除された1つのステップで動作します。 GUIマネージャーは、イベントハンドラーにメッセージを送信するように構成されています。ボタンプッシュはmyactionプログラムによって処理されることをイベントマネージャーに伝えます。ボタンが押されると、GUIマネージャーはメッセージをイベントハンドラーのキューに入れ、GUIの管理を開始します。イベントハンドラーはキューからメッセージを取得し、それがプッシュボタンであることを確認し、myactionプログラムを起動し、次のイベントの処理に進みます。通常、myactionプログラムは、独立したスレッドとして、または別個のプロセスとしても実行されます。

「イベントハンドラ」パターンはより複雑ですが、アクションが失敗した場合にはるかに堅牢でハングしにくいです。また、より応答性の高いGUIになります。

19
James Anderson

コールバックは、引数として別のプロシージャに渡すプロシージャです。パラメータを受け取るプロシージャは、それを呼び出すか、システム内の他のプロシージャが呼び出すことができるように共有できます。

イベントハンドラは、イベントが発生したときに呼び出されるプロシージャです。コールバックにすることができます。

45

イベントハンドラはコールバックの一種です。イベントが発生するたびに呼び出されます。この用語は通常、イベントがマウスの移動、何かのクリックなどのようなものであるユーザーインターフェイスの用語で使用されます。

30
cletus

この質問は非常に古いですが、このリンクは [〜#〜] msdn [〜#〜] から非常に興味深いものでした。この質問につまずく誰かがこのリンクから何かを得ることを願っています。

10
uriDium

コールバック(Wikipediaから):「他のコードへの引数として渡される実行可能コード」。
イベントハンドラ(Wikipediaから):「プログラムで受信した入力を処理する非同期コールバックサブルーチン」。

これは、私がいつも理解してきた方法です。イベントハンドラは、非常に特殊なタイプのコールバックです。

10
Esteban Araya

イベント-サーバー(従業員)とクライアント(ボス)を考えます。1人の従業員が多くのボスを持つことができます。従業員は、タスクを完了するとイベントを発生させ、ボスは従業員イベントをリッスンするかどうかを決定できます。従業員はパブリッシャーであり、ボスはサブスクライバーです。

コールバック-ボスは従業員にタスクを実行するように明確に要求し、タスクの終了時にボスに通知することを望んでいます。従業員は、タスクが完了したら、すべてのボスではなく、要求したボスのみに通知するようにします。部分的な仕事が完了した場合、従業員はボスに通知しません。すべてのタスクが完了した後のみになります。1人の上司のみが情報を要求し、従業員は1人の上司にのみ返信を投稿しました。

8
TanuAD

これのもう1つの側面は、イベントが過去に発生した何かを記述するのに対して、何かが発生しているときにコールバックがよく使用されることです。

イベントが発生すると、何かが発生したことが通知されます。コールバックを使用すると、何かに参加するように求められます。

ライブラリまたはフレームワークは、何かが発生したことを知らせるイベントを発行する場合があります。フレームワークは、プロセスに積極的に参加できるように、コードを(おそらくコールバックとして)プラグインできるポイントを提供します。

問題の一部は、イベント、コールバックが技術的なメカニズムだけでなく、より抽象的なプロセスを指すことです。

4
Tim Barrass

ジェームズアンダーソンの答えは最も詳細です。彼の答えを拡大します。コールバックとは、メソッドに引数として渡され、後で非同期に呼び出されることを意図したコードを指します。ただし、コールバックは、コールバック自体のプロセスの実装方法を定義しません。これは、コールバックの分類が始まる場所です。従来、コールバックプロセスは次のようになります。

  • 開発者はコールバックを定義し、それをライブラリ定義関数(呼び出しプロセスまたは検出プロセスがコールできるようにコールバックの処理方法を知っている関数)に渡します。ノードで、

var server = require('http').createServer(function(req, res){/* your code */});

createServerは、検出プロセスが正しいコールバック(この場合はfunction(req, res){/* your code */})を呼び出すことを確実にするライブラリ定義関数です。

  • 実行時に、検出プロセスはコールバックの直接の場所を受け取り(ライブラリ定義の関数がそれを行ったため)、それを呼び出します。これは2つのことを意味します:
    • ライブラリの開発者は、それぞれが異なるコールバック方法を持っている可能性があるため、常に異なる検出プロセスに対処する方法を知る必要があります。
    • また、コールバックを複数回呼び出す必要がある場合は、検出プロセスを処理する場合があります。例えば検出プロセスがGUIプロセスである場合、GUIエクスペリエンスをスムーズにするために、できるだけ少ないタスクでGUIスレッドを実行する必要があります。

したがって、コールバックのメカニズムを実装する必要が生じ、これらの2つの問題を解決しました。

  • ライブラリ関数がコールバックを登録し、検出されたプロセスがこれらの登録されたコールバックを呼び出す必要があるときに通知するための同時ポイントを定義する外部プロセス。
    • つまり、これらの両方のプロセスの開発者は、お互いの方法を実際に知らなくても、互いに独立して作業できるようになりました。
    • この外部プロセスは、イベントループ(ノード内など)として知られるようになりました。 「イベント」という用語は、検出プロセスによってイベントループに通知するプロセスであり、登録されたコールバックはイベントハンドラーとして知られるようになりました。
  • 外部プロセス(またはイベントループ)がイベントをキューに入れて実行したため、検出プロセスの負荷が軽減され、最高の状態に戻ることができました。

したがって、複数回発生したイベントについては、イベントループまたはイベントハンドラーがコールバックの実装方法になりました。ただし、元のコールバックは1回限りのイベントに優先されます検出プロセスを実際に処理しているわけではなく、効率的ではないため、1つのイベントだけにイベントループを設定する必要はありません。

  • 上記のノードjsコードは1回限りのイベントであり(クライアントのサーバーへの接続は1回限りのイベントであり、イベントハンドラーとして実装される応答は多数存在する可能性があるため)、単純なコールバックの例です。
1
supi

これらすべての答えがお互いにどのように異なるかが大好きです。

私はこれから結論付けます、用語の観点からイベントとコールバックは交換可能であるということです。特定のプログラミング言語またはフレームワークでの意味とは異なりますが、プラットフォームは好みの用語を選択する傾向があるためです。

0
Evert

基本的なメカニズムは似ていますが、セマンティクスは異なります。コールバックとイベントハンドラーの両方が非同期と呼ばれます。

コールバック関数は、通常、呼び出し元ルーチンから明示的に渡され、何らかの情報を要求します。しばらくしてから情報が返され、呼び出し先によってコールバックに引数として渡されます。この時点で、呼び出し元のルーチンはビジネスを完了します。多くの場合、コールバックはクロージャです-呼び出しルーチン内の構文上、多くの場合、名前のない(匿名)。 javascriptでは、次のようになります。

function caller() {
    someLibrary.getMeSomething(arg1, arg2, function(returnedData) {
        // this is the callback which will do something with returnedData
    });
}

したがって、呼び出し先(someLibrary.getMeSomething)には匿名のコールバック関数が与えられ、しばらくしてから、この関数はReturnedDataで呼び出されます。コールバックは、単一の受信者へのシングルショットイベントのようなものです。

イベントハンドラも「コールバック」されますが、通常はマウスクリック、ネットワークイベントなどの複数のイベントで長期間にわたって使用されます。また、複数のオブジェクトが同じイベントに関心を持っている場合があります。これらの理由から、通常はセットアップコード(オブジェクトの初期化など)でイベントを「サブスクライブ」または「登録」します。イベントハンドラーは、より一般的には名前付きメソッドです。通常、各イベントタイプは定数または文字列として識別されます。

したがって、Pythonのようになります。

class MyUIClass:

    def __init__(self):
        someUILib.register(someUILib.events.MOUSE_CLICK, self.my_mouse_click_handler);

    def my_mouse_click_handler(self, eventInfo):
        # do something with event
        if eventInfo.x < 100:
             print 'You clicked in the margin'
0
pwray

コールバックは、別の関数(メソッド)に引数として渡す関数(メソッド)です。パラメータを受け取る関数(メソッド)はそれを呼び出すか、システム内の他の関数(メソッド)が呼び出すことができるように共有できます。

イベントハンドラは、イベントが発生したときに呼び出される関数(メソッド)です。コールバックにすることができます。

0
trable