Разница между обработчиками событий и обратными вызовами - PullRequest
57 голосов
/ 15 января 2010

В чем разница между обработчиком событий и функцией обратного вызова?

Ответы [ 12 ]

44 голосов
/ 15 января 2010

Обратный вызов - это процедура, которую вы передаете в качестве аргумента другой процедуре. Процедура, получающая параметр, может вызывать его или делиться им, чтобы некоторые другие процедуры в системе могли вызывать его.

Обработчик события - это процедура, вызываемая при возникновении события. Это может быть обратный вызов.

30 голосов
/ 15 января 2010

Обработчик события - это тип обратного вызова. Он вызывается всякий раз, когда происходит событие. Этот термин обычно используется в терминах пользовательских интерфейсов, где такие события, как перемещение мыши, щелчок по чему-либо и т.

18 голосов
/ 15 января 2010

Вообще говоря, «обратный вызов» находится под контролем процесса обнаружения. Таким образом, вы говорите менеджеру GUI «вызов myaction при нажатии этой кнопки», а менеджер GUI вызывает действие при нажатии кнопки.

Обработчики событий, с другой стороны, работают за один шаг. Диспетчер графического интерфейса пользователя настроен на отправку сообщений обработчику событий. Вы сообщаете менеджеру событий, что нажатия кнопок обрабатываются программой myaction. Когда кнопка нажата, менеджер GUI помещает сообщение в очередь обработчика событий и начинает управление GUI. Обработчик событий получает сообщение из очереди, видит, что это нажатие кнопки, запускает программу myaction и переходит к обработке следующего события. Обычно программа myaction запускается как независимый поток или даже как отдельный процесс.

Хотя шаблон «обработчик событий» более сложный, он гораздо более устойчив и менее подвержен зависанию при сбое действия. Это также обеспечивает более отзывчивый графический интерфейс.

10 голосов
/ 15 мая 2013

Этот вопрос очень старый, но я нашел эту ссылку из MSDN очень интересной. Я надеюсь, что кто-нибудь еще, кто наткнется на этот вопрос, получит что-то по этой ссылке.

10 голосов
/ 15 января 2010

Обратный вызов (из Википедии) : "исполняемый код, который передается в качестве аргумента другому коду".
Обработчик событий (снова из Википедии) : «подпрограмма асинхронного обратного вызова, которая обрабатывает входные данные, полученные в программе».

Это то, как я всегда это понимал: обработчик событий - это очень специфический тип обратного вызова.

8 голосов
/ 13 декабря 2015

События - Подумайте о сервере (сотрудник) и клиенте (босс). Один сотрудник может иметь много боссов. Сотрудник Вызывает событие, когда он завершает задачу, и Боссы могут решить слушать событие Сотрудника или нет. Сотрудник является издателем, а начальство подписчиком.

Обратный вызов - Босс специально попросил сотрудника выполнить задание, и в конце задания Босс хочет получить уведомление. Сотрудник позаботится о том, чтобы, когда задание было выполнено, он уведомлял только Босса, который запросил, не обязательно всех Боссов. Сотрудник не будет уведомлять Босса, если частичная работа выполнена. Это будет только после того, как все задание выполнено. Только один босс запросил информацию, а сотрудник отправил ответ только одному боссу.

4 голосов
/ 19 ноября 2014

Другим аспектом этого является то, что события описывают то, что произошло в прошлом, тогда как обратный вызов часто используется, когда что-то происходит.

Когда происходит событие, вам говорят, что что-то случилось. Когда используется обратный вызов, вас просят принять участие в чем-либо.

Библиотека или фреймворк могут выдавать события, которые сообщают вам, что что-то произошло. Фреймворк предлагает вам точки, в которые вы можете подключить код (возможно, в виде обратных вызовов), чтобы вы могли активно участвовать в процессе.

Часть проблемы заключается в том, что событие, обратный вызов относится к техническим механизмам, а также к более абстрактным процессам.

1 голос
/ 09 апреля 2014

Ответ Джеймса Андерсона самый подробный. Расширяя свой ответ; Обратный вызов относится к любому коду, который передается в качестве аргумента методу и предназначен для последующего асинхронного вызова. Однако обратный вызов не определяет, как должен быть реализован сам процесс обратного вызова. Здесь начинается классификация обратных вызовов. Традиционно процесс обратного вызова будет выглядеть так:

  • разработчик определяет обратный вызов и передает его в определенную библиотекой функцию (которая знает, что делать с обратным вызовом, чтобы вызывающий процесс или процесс обнаружения мог ее вызвать), например, для. в узле,

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

createServer - это определенная библиотекой функция, которая гарантирует, что процесс обнаружения вызовет правильный обратный вызов, который в данном случае равен function(req, res){/* your code */}

  • во время выполнения процесс обнаружения получает прямое местоположение обратного вызова (потому что определенная библиотекой функция сделала это за вас) и вызывает его. Это будет означать 2 вещи:
    • разработчикам библиотеки всегда нужно знать, как обращаться с различными процессами обнаружения, поскольку у каждого может быть свой способ перезвона
    • и если обратный вызов необходимо вызывать несколько раз, он может поставить задачу на обнаружение. Например, если процесс обнаружения - это процесс с графическим интерфейсом, то вы бы хотели, чтобы поток с графическим интерфейсом выполнялся с как можно меньшим количеством задач, чтобы обеспечить удобство работы с графическим интерфейсом.

Таким образом, возникла необходимость в реализации механизма обратного вызова, который решил следующие 2 проблемы:

  • внешний процесс, который определил бы параллельную точку для библиотечной функции для регистрации обратных вызовов и для процесса обнаружения, чтобы уведомить о том, когда эти зарегистрированные обратные вызовы должны быть вызваны.
    • Это означало, что разработчики обоих этих процессов теперь могут работать независимо друг от друга, по-настоящему не зная путей друг друга.
    • Этот внешний процесс стал известен как цикл обработки событий (например, в узле). Термин «событие» - это просто процесс уведомления о цикле событий процессом обнаружения, и зарегистрированный обратный вызов стал известен как обработчик событий.
  • внешний процесс (или цикл событий) поставил в очередь события и выполнил их, таким образом снимая нагрузку с процесса обнаружения, который теперь мог вернуться к тому, что он делал лучше всего.

Таким образом, для событий, которые произошли несколько раз, цикл событий или обработчики событий стали способом реализации обратных вызовов, , в то время как исходные обратные вызовы все еще предпочтительнее для одноразовых событий , так как вы на самом деле не выполняете задачи обнаружение процесса и не нужно иметь цикл событий только для одного события, так как это не эффективно.

  • Приведенный выше код js узла является одноразовым событием (поскольку подключение к серверу для клиента является одноразовым событием, в то время как может быть много ответов, которые реализованы как обработчики событий) и является примером простого обратного вызова ,
0 голосов
/ 31 июля 2018

Обратный вызов - это функция (метод), которую вы передаете в качестве аргумента другой функции (методу). Функция (метод), принимающая параметр, может вызывать его или делиться им, чтобы другая функция (метод) в системе могла вызывать его.

Обработчик события - это функция (метод), вызываемая при возникновении события. Это может быть обратный вызов.

0 голосов
/ 08 сентября 2014

Базовые механизмы похожи, но семантика различна. И обратные вызовы, и обработчики событий называются асинхронно .

Функция обратного вызова обычно передается явным образом из подпрограммы вызывающей стороны для запроса некоторой информации. Информация возвращается через некоторое время и передается вызываемой стороной в качестве аргументов обратному вызову. В настоящее время процедура вызова завершает свою работу. Часто обратный вызов является закрытием - синтаксически внутри вызывающей подпрограммы и часто безымянным (анонимным). Это может выглядеть немного как ниже, в javascript:

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

Таким образом, вызываемый объект (someLibrary.getMeSomething) получает анонимную функцию обратного вызова, а через некоторое время эта функция вызывается с возвращенными данными. Обратный вызов похож на одноразовое событие для одного получателя.

Обработчики событий также «возвращаются», но обычно они используются в течение длительного периода для нескольких событий, таких как щелчки мыши, сетевые события и т. Д. Кроме того, несколько объектов могут интересоваться одним и тем же событием. По этим причинам вы обычно «подписываетесь» или «регистрируетесь» на события в коде установки (например, инициализация объекта), а обработчик событий обычно является именованным методом. Как правило, каждый тип события определяется как константа или строка.

Так что в 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'
...