Что такое функция обратного вызова?
Что такое функция обратного вызова?
Ответы:
Разработчиков часто смущает, что такое обратный вызов из-за названия проклятой вещи.
Функция обратного вызова - это функция, которая:
Хороший способ представить, как работает функция обратного вызова, состоит в том, что это функция, которая «вызывается сзади » функции, в которую она передается.
Может быть, лучшим именем будет функция «вызов после» .
Эта конструкция очень полезна для асинхронного поведения, когда мы хотим, чтобы действие происходило всякий раз, когда завершается предыдущее событие.
псевдокод:
// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
printout("The number you provided is: " + number);
}
// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
printout("I have finished printing numbers.");
}
// Driver method
funct event() {
printANumber(6, printFinishMessage);
}
Результат, если вы вызвали event ():
The number you provided is: 6
I have finished printing numbers.
Порядок вывода здесь важен. Поскольку функции обратного вызова вызываются позже, «Я закончил печатать номера» печатается последним, а не первым.
Обратные вызовы являются так называемыми из-за их использования с языками указателей. Если вы не используете один из них, не работайте над именем «обратный вызов». Просто поймите, что это просто имя для описания метода, который передается в качестве аргумента другому методу, например, когда вызывается родительский метод (любое условие, например, нажатие кнопки, отметка таймера и т. Д.) И его тело метода завершается, затем вызывается функция обратного вызова.
Некоторые языки поддерживают конструкции, в которых поддерживаются несколько аргументов функции обратного вызова, и вызываются на основе завершения родительской функции (т. Е. Один обратный вызов вызывается в случае успешного завершения родительской функции, другой вызывается в случае, если родительская функция выбрасывает конкретная ошибка и т. д.).
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
следующим образом:
factorial(really_big_number, what_to_do_with_the_result)
Второй параметр, what_to_do_with_the_result
это функция, которую вы отправляете factorial
, в надежде, что factorial
вызовет ее в результате перед возвратом.
Да, это означает, что это factorial
должно быть написано для поддержки обратных вызовов.
Теперь предположим, что вы хотите иметь возможность передать параметр в ваш обратный вызов. Теперь вы не можете, потому что вы не собираетесь это называть, factorial
это так. Поэтому factorial
необходимо написать, чтобы вы могли передать свои параметры, и он просто передаст их вашему обратному вызову, когда вызовет его. Это может выглядеть так:
factorial (number, callback, params)
{
result = number! // i can make up operators in my pseudocode
callback (result, params)
}
Теперь, когда factorial
это разрешено, ваш обратный вызов может выглядеть так:
logIt (number, logger)
{
logger.log(number)
}
и ваш призыв к factorial
будет
factorial(42, logIt, logger)
Что если вы хотите что-то вернуть logIt
? Ну, ты не можешь, потому что factorial
не обращает на это внимания.
Ну, почему нельзя factorial
просто вернуть то, что возвращает ваш обратный вызов?
Поскольку выполнение предназначено для передачи factorial
обратному вызову после его завершения, оно действительно не должно ничего возвращать вызывающей стороне. И в идеале, он каким-то образом запустит свою работу в другом потоке / процессе / машине и сразу же вернется, чтобы вы могли продолжить, возможно, что-то вроде этого:
factorial(param_1, param_2, ...)
{
new factorial_worker_task(param_1, param_2, ...);
return;
}
Теперь это «асинхронный вызов», что означает, что когда вы вызываете его, он немедленно возвращается, но еще не выполнил свою работу. Таким образом, вам нужны механизмы, чтобы проверить его и получить его результат, когда он будет завершен, и ваша программа стала более сложной в этом процессе.
И, кстати, используя этот шаблон, вы factorial_worker_task
можете запустить ваш обратный вызов асинхронно и немедленно вернуться.
Ответ заключается в том, чтобы оставаться в рамках модели обратного вызова. Всякий раз, когда вы хотите написать
a = f()
g(a)
и f
должен вызываться асинхронно, вместо этого вы будете писать
f(g)
где g
передается в качестве обратного вызова.
Это в корне меняет топологию потока вашей программы и требует некоторого привыкания.
Ваш язык программирования может очень вам помочь, предоставляя вам возможность создавать функции на лету. В приведенном выше коде функция g
может быть такой же маленькой, как и print (2*a+1)
. Если ваш язык требует, чтобы вы определили это как отдельную функцию с совершенно ненужным именем и подписью, то ваша жизнь станет неприятной, если вы будете часто использовать этот шаблон.
Если, с другой стороны, ваш язык позволяет вам создавать лямбды, то вы в гораздо лучшей форме. Затем вы в конечном итоге написать что-то вроде
f( func(a) { 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
. function action(x, y, callback) {
return callback(x, y);
}
function multiplication(x, y) {
return x * y;
}
function addition(x, y) {
return x + y;
}
alert(action(10, 10, multiplication)); // output: 100
alert(action(10, 10, addition)); // output: 20
В SOA обратный вызов позволяет подключаемым модулям получать доступ к сервисам из контейнера / среды.
Аналогия: обратные вызовы. Асинхронный. Неблокирующий
пример из реальной жизни для обратного вызова
Call After будет лучшим именем, чем глупое имя, callback . Когда или если условие выполняется внутри функции, вызовите другую функцию, функцию Call After , полученную в качестве аргумента.
Вместо того, чтобы жестко кодировать внутреннюю функцию внутри функции, пишется функция, принимающая в качестве аргумента уже написанную функцию Call After . Вызова После того, как может вызываться на основе изменений состояния детектируется кода в функции принимающей аргумент.
Функция обратного вызова - это функция, которую вы указываете для существующей функции / метода, которая вызывается, когда действие завершено, требует дополнительной обработки и т. Д.
Например, в Javascript или, более конкретно, в jQuery вы можете указать аргумент обратного вызова, который будет вызываться после завершения анимации.
В PHP preg_replace_callback()
функция позволяет предоставить функцию, которая будет вызываться при сопоставлении регулярного выражения, передавая строку (и), совпадающую в качестве аргументов.
посмотрите на изображение :)
Основная программа вызывает библиотечную функцию (которая также может быть функцией системного уровня) с именем функции обратного вызова. Эта функция обратного вызова может быть реализована несколькими способами. Основная программа выбирает один обратный вызов согласно требованию.
Наконец, библиотечная функция вызывает функцию обратного вызова во время выполнения.
Простой ответ на этот вопрос заключается в том, что функция обратного вызова - это функция, которая вызывается через указатель на функцию. Если вы передаете указатель (адрес) функции в качестве аргумента другому, когда этот указатель используется для вызова функции, на которую он указывает, говорят, что обратный вызов сделан
Предположим, у нас есть функция, в sort(int *arraytobesorted,void (*algorithmchosen)(void))
которой она может принимать указатель на функцию в качестве аргумента, который можно использовать в какой-то момент в sort()
реализации. Затем здесь код, к которому обращается указатель функции, algorithmchosen
вызывается как функция обратного вызова .
И видим преимущество в том, что мы можем выбрать любой алгоритм, например:
1. algorithmchosen = bubblesort
2. algorithmchosen = heapsort
3. algorithmchosen = mergesort ...
Которые, скажем, были реализованы с прототипом:
1. `void bubblesort(void)`
2. `void heapsort(void)`
3. `void mergesort(void)` ...
Эта концепция используется для достижения полиморфизма в объектно-ориентированном программировании.
«В компьютерном программировании обратный вызов - это ссылка на исполняемый код или фрагмент исполняемого кода, который передается в качестве аргумента другому коду. Это позволяет программному уровню более низкого уровня вызывать подпрограмму (или функцию), определенную на уровне более высокого уровня ». - Википедия
Обратный вызов в C с использованием указателя на функцию
В C обратный вызов реализован с использованием указателя функций. Указатель на функцию - как следует из названия, является указателем на функцию.
Например, int (* ptrFunc) ();
Здесь ptrFunc - указатель на функцию, которая не принимает аргументов и возвращает целое число. НЕ забывайте ставить в скобках, иначе компилятор будет считать, что ptrFunc - это обычное имя функции, которое ничего не берет и возвращает указатель на целое число.
Вот некоторый код для демонстрации указателя функции.
#include<stdio.h>
int func(int, int);
int main(void)
{
int result1,result2;
/* declaring a pointer to a function which takes
two int arguments and returns an integer as result */
int (*ptrFunc)(int,int);
/* assigning ptrFunc to func's address */
ptrFunc=func;
/* calling func() through explicit dereference */
result1 = (*ptrFunc)(10,20);
/* calling func() through implicit dereference */
result2 = ptrFunc(10,20);
printf("result1 = %d result2 = %d\n",result1,result2);
return 0;
}
int func(int x, int y)
{
return x+y;
}
Теперь давайте попробуем понять концепцию Callback в C, используя указатель на функцию.
Полная программа имеет три файла: callback.c, reg_callback.h и reg_callback.c.
/* callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* callback function definition goes here */
void my_callback(void)
{
printf("inside my_callback\n");
}
int main(void)
{
/* initialize function pointer to
my_callback */
callback ptr_my_callback=my_callback;
printf("This is a program demonstrating function callback\n");
/* register our callback function */
register_callback(ptr_my_callback);
printf("back inside main program\n");
return 0;
}
/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);
/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
printf("inside register_callback\n");
/* calling our callback function my_callback */
(*ptr_reg_callback)();
}
Если мы запустим эту программу, вывод будет
Это программа, демонстрирующая обратный вызов функции внутри register_callback внутри my_callback назад внутри основной программы
Функция верхнего уровня вызывает функцию нижнего уровня как обычный вызов, а механизм обратного вызова позволяет функции нижнего уровня вызывать функцию верхнего уровня через указатель на функцию обратного вызова.
Обратный вызов в Java с использованием интерфейса
В Java нет понятия указателя на функцию. Он реализует механизм обратного вызова через механизм интерфейса. Здесь вместо указателя на функцию мы объявляем интерфейс, имеющий метод, который будет вызываться, когда вызываемый объект завершит свою задачу.
Позвольте мне продемонстрировать это на примере:
Интерфейс обратного вызова
public interface Callback
{
public void notify(Result result);
}
Абонент или класс более высокого уровня
public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee
//Other functionality
//Call the Asynctask
ce.doAsynctask();
public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}
Функция Callee или нижнего уровня
public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}
doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}
Обратный вызов с использованием шаблона EventListener
Этот шаблон используется для уведомления от 0 до n номеров Наблюдателей / Слушателей о том, что определенная задача выполнена
Разница между механизмом обратного вызова и механизмом EventListener / Observer заключается в том, что при обратном вызове вызываемый абонент уведомляет одного вызывающего, тогда как в Eventlisener / Observer вызываемый может уведомить любого, кто заинтересован в этом событии (уведомление может быть передано некоторым другим частям приложение, которое не вызвало задачу)
Позвольте мне объяснить это на примере.
Интерфейс событий
public interface Events {
public void clickEvent();
public void longClickEvent();
}
Виджет класса
package com.som_itsolutions.training.java.exampleeventlistener;
import java.util.ArrayList;
import java.util.Iterator;
public class Widget implements Events{
ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>();
ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();
@Override
public void clickEvent() {
// TODO Auto-generated method stub
Iterator<OnClickEventListener> it = mClickEventListener.iterator();
while(it.hasNext()){
OnClickEventListener li = it.next();
li.onClick(this);
}
}
@Override
public void longClickEvent() {
// TODO Auto-generated method stub
Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
while(it.hasNext()){
OnLongClickEventListener li = it.next();
li.onLongClick(this);
}
}
public interface OnClickEventListener
{
public void onClick (Widget source);
}
public interface OnLongClickEventListener
{
public void onLongClick (Widget source);
}
public void setOnClickEventListner(OnClickEventListener li){
mClickEventListener.add(li);
}
public void setOnLongClickEventListner(OnLongClickEventListener li){
mLongClickEventListener.add(li);
}
}
Кнопка класса
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
Флажок класса
public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}
Класс деятельности
пакет com.som_itsolutions.training.java.exampleeventlistener;
public class Activity implements Widget.OnClickEventListener
{
public Button mButton;
public CheckBox mCheckBox;
private static Activity mActivityHandler;
public static Activity getActivityHandle(){
return mActivityHandler;
}
public Activity ()
{
mActivityHandler = this;
mButton = new Button();
mButton.setOnClickEventListner(this);
mCheckBox = new CheckBox();
mCheckBox.setOnClickEventListner(this);
}
public void onClick (Widget source)
{
if(source == mButton){
mButton.setButtonText("Thank you for clicking me...");
System.out.println(((Button) mButton).getButtonText());
}
if(source == mCheckBox){
if(mCheckBox.isChecked()==false){
mCheckBox.setCheck(true);
System.out.println("The checkbox is checked...");
}
else{
mCheckBox.setCheck(false);
System.out.println("The checkbox is not checked...");
}
}
}
public void doSomeWork(Widget source){
source.clickEvent();
}
}
Другой класс
public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}
Основной класс
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}
Как видно из приведенного выше кода, у нас есть интерфейс с названием 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 ...).
Одной из важных областей использования является то, что вы регистрируете одну из своих функций в качестве дескриптора (то есть обратного вызова), а затем отправляете сообщение / вызываете некоторую функцию для выполнения некоторой работы или обработки. Теперь, когда обработка завершена, вызываемая функция будет вызывать нашу зарегистрированную функцию (т. Е. Теперь выполнен обратный вызов), что указывает на то, что обработка завершена.
Эта ссылка на Википедию довольно хорошо объясняет графически.
Функция обратного вызова, также известная как функция высшего порядка, представляет собой функцию, которая передается другой функции в качестве параметра, и функция обратного вызова вызывается (или выполняется) внутри родительской функции.
$("#button_1").click(function() {
alert("button 1 Clicked");
});
Здесь мы передаем функцию в качестве параметра методу click. И метод click вызовет (или выполнит) функцию обратного вызова, которую мы передали ему.
Функция обратного вызова Функция, переданная другой функции в качестве аргумента.
function test_function(){
alert("Hello world");
}
setTimeout(test_function, 2000);
Примечание. В приведенном выше примере test_function используется в качестве аргумента для функции setTimeout.