Что такое функция обратного вызова?
language-agnostic
callback
Cheekysoft
источник
источник
Ответы:
Разработчиков часто смущает, что такое обратный вызов из-за названия проклятой вещи.
Функция обратного вызова - это функция, которая:
Хороший способ представить, как работает функция обратного вызова, состоит в том, что это функция, которая «вызывается сзади » функции, в которую она передается.
Может быть, лучшим именем будет функция «вызов после» .
Эта конструкция очень полезна для асинхронного поведения, когда мы хотим, чтобы действие происходило всякий раз, когда завершается предыдущее событие.
псевдокод:
Результат, если вы вызвали event ():
Порядок вывода здесь важен. Поскольку функции обратного вызова вызываются позже, «Я закончил печатать номера» печатается последним, а не первым.
Обратные вызовы являются так называемыми из-за их использования с языками указателей. Если вы не используете один из них, не работайте над именем «обратный вызов». Просто поймите, что это просто имя для описания метода, который передается в качестве аргумента другому методу, например, когда вызывается родительский метод (любое условие, например, нажатие кнопки, отметка таймера и т. Д.) И его тело метода завершается, затем вызывается функция обратного вызова.
Некоторые языки поддерживают конструкции, в которых поддерживаются несколько аргументов функции обратного вызова, и вызываются на основе завершения родительской функции (т. Е. Один обратный вызов вызывается в случае успешного завершения родительской функции, другой вызывается в случае, если родительская функция выбрасывает конкретная ошибка и т. д.).
источник
once its parent method completes, the function which this argument represents is then called
. Таким образом, если функция передается другой функции в качестве аргумента, но вызывается из середины времени выполнения родительской функции, какparent(cb) {dostuff1(); cb(); dostuff2()}
тогда, она не считаетсяcallback
функцией?Непрозрачное определение
Функция обратного вызова - это функция, которую вы предоставляете другому фрагменту кода, что позволяет ему вызываться этим кодом.
Придуманный пример
Зачем тебе это делать? Допустим, есть служба, которую нужно вызвать. Если сервис возвращается сразу, вы просто:
Например, предположим, что служба была
factorial
функцией. Когда вы хотите получить значение5!
, вы вызываете егоfactorial(5)
и выполняете следующие шаги:Ваше текущее местоположение выполнения сохранено (в стеке, но это не важно)
Исполнение передано
factorial
Когда
factorial
завершается, он помещает результат туда, куда вы можете добраться до негоКазнь возвращается туда, где она была в [1]
Теперь предположим, что это
factorial
заняло очень много времени, потому что вы даете ему огромные цифры, и он должен работать на каком-то суперкомпьютерном кластере. Допустим, вы ожидаете, что для возврата результата потребуется 5 минут. Вы могли бы:Сохраняйте свой дизайн и запускайте программу ночью, когда вы спите, чтобы не смотреть на экран половину времени
Разработайте свою программу, чтобы делать другие вещи, пока
factorial
она делает свое делоЕсли вы выберете второй вариант, обратные вызовы могут работать на вас.
Сквозной дизайн
Чтобы использовать шаблон обратного вызова, вам нужно иметь возможность вызывать
factorial
следующим образом:Второй параметр,
what_to_do_with_the_result
это функция, которую вы отправляетеfactorial
, в надежде, чтоfactorial
вызовет ее в результате перед возвратом.Да, это означает, что это
factorial
должно быть написано для поддержки обратных вызовов.Теперь предположим, что вы хотите иметь возможность передать параметр в ваш обратный вызов. Теперь вы не можете, потому что вы не собираетесь это называть,
factorial
это так. Поэтомуfactorial
необходимо написать, чтобы вы могли передать свои параметры, и он просто передаст их вашему обратному вызову, когда вызовет его. Это может выглядеть так:Теперь, когда
factorial
это разрешено, ваш обратный вызов может выглядеть так:и ваш призыв к
factorial
будетЧто если вы хотите что-то вернуть
logIt
? Ну, ты не можешь, потому чтоfactorial
не обращает на это внимания.Ну, почему нельзя
factorial
просто вернуть то, что возвращает ваш обратный вызов?Сделать это неблокирующим
Поскольку выполнение предназначено для передачи
factorial
обратному вызову после его завершения, оно действительно не должно ничего возвращать вызывающей стороне. И в идеале, он каким-то образом запустит свою работу в другом потоке / процессе / машине и сразу же вернется, чтобы вы могли продолжить, возможно, что-то вроде этого:Теперь это «асинхронный вызов», что означает, что когда вы вызываете его, он немедленно возвращается, но еще не выполнил свою работу. Таким образом, вам нужны механизмы, чтобы проверить его и получить его результат, когда он будет завершен, и ваша программа стала более сложной в этом процессе.
И, кстати, используя этот шаблон, вы
factorial_worker_task
можете запустить ваш обратный вызов асинхронно и немедленно вернуться.Ну так что ты делаешь?
Ответ заключается в том, чтобы оставаться в рамках модели обратного вызова. Всякий раз, когда вы хотите написать
и
f
должен вызываться асинхронно, вместо этого вы будете писатьгде
g
передается в качестве обратного вызова.Это в корне меняет топологию потока вашей программы и требует некоторого привыкания.
Ваш язык программирования может очень вам помочь, предоставляя вам возможность создавать функции на лету. В приведенном выше коде функция
g
может быть такой же маленькой, как иprint (2*a+1)
. Если ваш язык требует, чтобы вы определили это как отдельную функцию с совершенно ненужным именем и подписью, то ваша жизнь станет неприятной, если вы будете часто использовать этот шаблон.Если, с другой стороны, ваш язык позволяет вам создавать лямбды, то вы в гораздо лучшей форме. Затем вы в конечном итоге написать что-то вроде
что намного приятнее
Как пройти обратный звонок
Как бы вы передали функцию обратного вызова
factorial
? Ну, вы могли бы сделать это несколькими способами.Если вызываемая функция выполняется в том же процессе, вы можете передать указатель на функцию
Или, может быть, вы хотите сохранить словарь
fn name --> fn ptr
в вашей программе, в этом случае вы можете передать имяВозможно, ваш язык позволяет вам определять функцию на месте, возможно, как лямбда! Внутренне это создает какой-то объект и передает указатель, но вам не нужно об этом беспокоиться.
Возможно, вызываемая вами функция выполняется на совершенно отдельной машине, и вы вызываете ее, используя сетевой протокол, такой как HTTP. Вы можете представить свой обратный вызов как функцию, вызываемую по HTTP, и передать ее URL.
Вы поняли идею.
Недавний рост обратных вызовов
В эту эру Интернета, в которую мы вступили, службы, к которым мы обращаемся, часто находятся в сети. Мы часто не имеем никакого контроля над этими службами, то есть мы не писали их, мы не поддерживаем их, мы не можем гарантировать, что они работают или как они работают.
Но мы не можем ожидать, что наши программы будут блокироваться, пока мы ожидаем ответа этих служб. Осознавая это, поставщики услуг часто разрабатывают API, используя шаблон обратного вызова.
JavaScript очень хорошо поддерживает обратные вызовы, например, с лямбдами и замыканиями. И в мире JavaScript много активности, как в браузере, так и на сервере. Есть даже платформы JavaScript, разрабатываемые для мобильных устройств.
По мере продвижения вперед все больше и больше людей будут писать асинхронный код, для которого это понимание будет необходимо.
источник
Обратите внимание, что обратный вызов - это одно слово.
Страница обратного вызова Википедии объясняет это очень хорошо.
цитата со страницы википедии:
источник
Непрофессионал ответил бы, что это функция, которая вызывается не вами, а пользователем или браузером после определенного события или после обработки некоторого кода.
источник
Функция обратного вызова - это функция, которая должна вызываться при выполнении определенного условия. Вместо немедленного вызова, функция обратного вызова вызывается в определенный момент в будущем.
Обычно он используется, когда запускается задача, которая завершится асинхронно (т.е. завершится через некоторое время после возврата вызывающей функции).
Например, функция для запроса веб-страницы может потребовать, чтобы ее вызывающая сторона предоставила функцию обратного вызова, которая будет вызываться после завершения загрузки веб-страницы.
источник
"...when a condition is met"
но я думал, что обратные вызовы вызываются, когда родительская функция завершает выполнение и не зависит от условий (?).Обратные вызовы проще всего описать в терминах телефонной системы. Функциональный вызов аналогичен вызову кого-либо по телефону, задает ему вопрос, получает ответ и вешает трубку; добавление обратного вызова изменяет аналогию, так что после того, как вы зададите ей вопрос, вы также дадите ей свое имя и номер, чтобы она могла перезвонить вам с ответом.
- Пол Якубик, "Реализации обратного вызова в C ++"
источник
Я полагаю, что этот «обратный вызов» жаргон был ошибочно использован во многих местах. Мое определение будет что-то вроде:
Я думаю, что люди просто читают первое предложение определения вики:
Я работал со многими API, вижу множество плохих примеров. Многие люди склонны называть указатель на функцию (ссылка на исполняемый код) или анонимные функции (часть исполняемого кода) «обратным вызовом», если они просто функции, зачем вам другое имя для этого?
На самом деле, только второе предложение в определении вики раскрывает различия между функцией обратного вызова и нормальной функцией:
так что разница в том, кому вы собираетесь передать функцию и как будет вызываться ваша переданная функция. Если вы просто определяете функцию, передаете ее другой функции и вызываете ее непосредственно в теле этой функции, не вызывайте ее как обратный вызов. В определении сказано, что переданная вами функция будет вызываться функцией «нижнего уровня».
Я надеюсь, что люди могут перестать использовать это слово в неоднозначном контексте, оно не может помочь людям понять лучше только хуже.
источник
Давайте будем простыми. Что такое функция обратного вызова?
Пример по Притче и Аналогии
У меня есть секретарь. Каждый день я прошу ее: (i) отвезти исходящую почту фирмы на почту, а после того, как она это сделает, выполнить: (ii) любую задачу, которую я написал для нее на одной из этих записок .
Теперь, какова задача на заметку? Задача меняется день ото дня.
Предположим, именно в этот день я требую от нее распечатать некоторые документы. Поэтому я записываю это в заметку и прикрепляю ее к ее столу вместе с исходящей почтой, которую она должна отправить.
В итоге:
Функция обратного вызова - это вторая задача: распечатать эти документы. Потому что это делается ПОСЛЕ того, как почта отбрасывается, а также потому, что ей дается липкая записка с указанием напечатать документ вместе с почтой, которую она должна отправить.
Давайте теперь связать это с лексикой программирования
Вот и все. Ничего больше. Я надеюсь, что это прояснило для вас - и если нет, оставьте комментарий, и я сделаю все возможное, чтобы уточнить.
источник
Это делает обратные вызовы похожими на операторы возврата в конце методов.
Я не уверен, что это то, что они есть.
Я думаю, что обратные вызовы - это на самом деле вызов функции, как следствие вызова и завершения другой функции.
Я также думаю, что обратные вызовы предназначены для обращения к исходному вызову, в некотором роде: «Эй! То, что вы просили? Я сделал это - просто подумал, что дам вам знать - вернемся к вам».
источник
otherFunction
) в качестве параметра, а функция обратного вызова вызывается (или выполняется) внутриotherFunction
.В SOA обратный вызов позволяет подключаемым модулям получать доступ к сервисам из контейнера / среды.
Аналогия: обратные вызовы. Асинхронный. Неблокирующий
пример из реальной жизни для обратного вызова
источник
Call After будет лучшим именем, чем глупое имя, callback . Когда или если условие выполняется внутри функции, вызовите другую функцию, функцию Call After , полученную в качестве аргумента.
Вместо того, чтобы жестко кодировать внутреннюю функцию внутри функции, пишется функция, принимающая в качестве аргумента уже написанную функцию Call After . Вызова После того, как может вызываться на основе изменений состояния детектируется кода в функции принимающей аргумент.
источник
Функция обратного вызова - это функция, которую вы указываете для существующей функции / метода, которая вызывается, когда действие завершено, требует дополнительной обработки и т. Д.
Например, в Javascript или, более конкретно, в jQuery вы можете указать аргумент обратного вызова, который будет вызываться после завершения анимации.
В PHP
preg_replace_callback()
функция позволяет предоставить функцию, которая будет вызываться при сопоставлении регулярного выражения, передавая строку (и), совпадающую в качестве аргументов.источник
посмотрите на изображение :)
Основная программа вызывает библиотечную функцию (которая также может быть функцией системного уровня) с именем функции обратного вызова. Эта функция обратного вызова может быть реализована несколькими способами. Основная программа выбирает один обратный вызов согласно требованию.
Наконец, библиотечная функция вызывает функцию обратного вызова во время выполнения.
источник
Простой ответ на этот вопрос заключается в том, что функция обратного вызова - это функция, которая вызывается через указатель на функцию. Если вы передаете указатель (адрес) функции в качестве аргумента другому, когда этот указатель используется для вызова функции, на которую он указывает, говорят, что обратный вызов сделан
источник
Предположим, у нас есть функция, в
sort(int *arraytobesorted,void (*algorithmchosen)(void))
которой она может принимать указатель на функцию в качестве аргумента, который можно использовать в какой-то момент вsort()
реализации. Затем здесь код, к которому обращается указатель функции,algorithmchosen
вызывается как функция обратного вызова .И видим преимущество в том, что мы можем выбрать любой алгоритм, например:
Которые, скажем, были реализованы с прототипом:
Эта концепция используется для достижения полиморфизма в объектно-ориентированном программировании.
источник
«В компьютерном программировании обратный вызов - это ссылка на исполняемый код или фрагмент исполняемого кода, который передается в качестве аргумента другому коду. Это позволяет программному уровню более низкого уровня вызывать подпрограмму (или функцию), определенную на уровне более высокого уровня ». - Википедия
Обратный вызов в C с использованием указателя на функцию
В C обратный вызов реализован с использованием указателя функций. Указатель на функцию - как следует из названия, является указателем на функцию.
Например, int (* ptrFunc) ();
Здесь ptrFunc - указатель на функцию, которая не принимает аргументов и возвращает целое число. НЕ забывайте ставить в скобках, иначе компилятор будет считать, что ptrFunc - это обычное имя функции, которое ничего не берет и возвращает указатель на целое число.
Вот некоторый код для демонстрации указателя функции.
Теперь давайте попробуем понять концепцию Callback в C, используя указатель на функцию.
Полная программа имеет три файла: callback.c, reg_callback.h и reg_callback.c.
Если мы запустим эту программу, вывод будет
Это программа, демонстрирующая обратный вызов функции внутри register_callback внутри my_callback назад внутри основной программы
Функция верхнего уровня вызывает функцию нижнего уровня как обычный вызов, а механизм обратного вызова позволяет функции нижнего уровня вызывать функцию верхнего уровня через указатель на функцию обратного вызова.
Обратный вызов в Java с использованием интерфейса
В Java нет понятия указателя на функцию. Он реализует механизм обратного вызова через механизм интерфейса. Здесь вместо указателя на функцию мы объявляем интерфейс, имеющий метод, который будет вызываться, когда вызываемый объект завершит свою задачу.
Позвольте мне продемонстрировать это на примере:
Интерфейс обратного вызова
Абонент или класс более высокого уровня
Функция Callee или нижнего уровня
Обратный вызов с использованием шаблона EventListener
Этот шаблон используется для уведомления от 0 до n номеров Наблюдателей / Слушателей о том, что определенная задача выполнена
Разница между механизмом обратного вызова и механизмом EventListener / Observer заключается в том, что при обратном вызове вызываемый абонент уведомляет одного вызывающего, тогда как в Eventlisener / Observer вызываемый может уведомить любого, кто заинтересован в этом событии (уведомление может быть передано некоторым другим частям приложение, которое не вызвало задачу)
Позвольте мне объяснить это на примере.
Интерфейс событий
Виджет класса
Кнопка класса
Флажок класса
Класс деятельности
пакет com.som_itsolutions.training.java.exampleeventlistener;
Другой класс
Основной класс
Как видно из приведенного выше кода, у нас есть интерфейс с названием events, который в основном перечисляет все события, которые могут произойти для нашего приложения. Класс Widget является базовым классом для всех компонентов пользовательского интерфейса, таких как Button, Checkbox. Эти компоненты пользовательского интерфейса являются объектами, которые фактически получают события из кода платформы. Класс Widget реализует интерфейс Events, а также имеет два вложенных интерфейса: OnClickEventListener и OnLongClickEventListener.
Эти два интерфейса отвечают за прослушивание событий, которые могут произойти в компонентах пользовательского интерфейса, производных от виджетов, таких как Button или Checkbox. Поэтому, если мы сравним этот пример с более ранним примером Callback с использованием интерфейса Java, эти два интерфейса будут работать как интерфейс Callback. Таким образом, код более высокого уровня (Здесь Activity) реализует эти два интерфейса. И всякий раз, когда событие происходит с виджетом, будет вызываться код более высокого уровня (или метод этих интерфейсов, реализованный в коде более высокого уровня, который здесь называется Activity).
Теперь позвольте мне обсудить основные различия между шаблонами Callback и Eventlistener. Как мы уже упоминали, используя Callback, Callee может уведомить только одного абонента. Но в случае шаблона EventListener любая другая часть или класс приложения может регистрироваться для событий, которые могут происходить на кнопке или флажке. Примером такого класса является класс OtherClass. Если вы увидите код OtherClass, вы обнаружите, что он зарегистрировал себя в качестве прослушивателя ClickEvent, что может происходить в кнопке, определенной в Activity. Интересно, что помимо Activity (Вызывающий объект), этот OtherClass также будет уведомляться всякий раз, когда происходит событие нажатия кнопки.
источник
Функция обратного вызова - это функция, которую вы передаете (в качестве ссылки или указателя) определенной функции или объекту. Эта функция или объект будет вызывать эту функцию обратно в любое время, возможно, несколько раз, для любых целей:
...
Таким образом, описание обратного вызова как функции, вызываемой в конце другой функции или задачи, чрезмерно упрощается (даже если это общий случай использования).
источник
Обратный вызов - это идея передать функцию в качестве параметра другой функции и вызвать ее после завершения процесса.
Если вы получили концепцию обратного вызова через удивительные ответы выше, я рекомендую вам изучить основы его идеи.
«Что заставило их (компьютерных ученых) разработать обратный вызов?» Вы можете изучить проблему, которая блокирует (особенно блокирует пользовательский интерфейс), и обратный вызов не является единственным решением. Есть много других решений (например: Thread, Futures, Promises ...).
источник
Одной из важных областей использования является то, что вы регистрируете одну из своих функций в качестве дескриптора (то есть обратного вызова), а затем отправляете сообщение / вызываете некоторую функцию для выполнения некоторой работы или обработки. Теперь, когда обработка завершена, вызываемая функция будет вызывать нашу зарегистрированную функцию (т. Е. Теперь выполнен обратный вызов), что указывает на то, что обработка завершена.
Эта ссылка на Википедию довольно хорошо объясняет графически.
источник
Функция обратного вызова, также известная как функция высшего порядка, представляет собой функцию, которая передается другой функции в качестве параметра, и функция обратного вызова вызывается (или выполняется) внутри родительской функции.
Здесь мы передаем функцию в качестве параметра методу click. И метод click вызовет (или выполнит) функцию обратного вызова, которую мы передали ему.
источник
Функция обратного вызова Функция, переданная другой функции в качестве аргумента.
Примечание. В приведенном выше примере test_function используется в качестве аргумента для функции setTimeout.
источник