Что такое функция обратного вызова?

Что такое функция обратного вызова?

Ответ 1

Разработчики часто путаются тем, что обратный вызов происходит из-за имени проклятой вещи.

Функция обратного вызова - это функция, которая:

  • доступный другой функцией, и
  • вызывается после первой функции, если эта первая функция завершается

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

Возможно, лучшим именем будет функция "call after".

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

псевдокод:

// 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.

Порядок вывода здесь важен. Поскольку функции обратного вызова вызываются впоследствии, "Я закончил печатать цифры" печатается последним, а не первым.

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

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

Ответ 2

Непрозрачное определение

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

Проприведенный пример

Зачем вам это нужно? Скажем, есть служба, которую нужно вызвать. Если служба немедленно возвращается, вы просто:

  • Назовите его
  • Дождитесь результата
  • Продолжайте, как только результат появится в

Например, предположим, что службой была функция factorial. Если вы хотите значение 5!, вы будете вызывать factorial(5), и будут выполняться следующие шаги:

  • Ваше текущее место выполнения сохраняется (в стеке, но это не важно)

  • Выполнение передается factorial

  • Когда factorial завершается, он помещает результат где-нибудь, с которым вы можете добраться до него

  • Выполнение возвращается туда, где оно было в [1]

Теперь предположим, что factorial занял очень много времени, потому что вы даете ему огромные числа, и он должен запускаться на каком-то суперкомпьютерном кластере somwhere. Скажем, вы ожидаете, что за 5 минут вернется ваш результат. Вы могли:

  • Храните свой дизайн и запускайте свою программу ночью, когда вы спите, чтобы вы не смотрели на экран в течение половины времени

  • Создайте свою программу для выполнения других действий, пока factorial делает свою работу

Если вы выберете второй вариант, для вас могут работать обратные вызовы.

Концевой дизайн

Чтобы использовать шаблон обратного вызова, вы должны иметь возможность вызывать factorial следующим образом:

factorial(really_big_number, what_to_do_with_the_result)

Второй параметр what_to_do_with_the_result - это функция, которую вы отправляете вместе с factorial, в надежде, что factorial вызовет ее по ее результату перед возвратом.

Да, это означает, что factorial должен быть написан для поддержки обратных вызовов.

Теперь предположим, что вы хотите иметь возможность передать параметр для вашего обратного вызова. Теперь вы не можете, потому что вы не собираетесь его называть, factorial is. Поэтому 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, разработанные для мобильных устройств.

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

Ответ 3

Обратите внимание, что обратный вызов - это одно слово.

Страница обратного вызова wikipedia объясняет это очень хорошо.

цитата из страницы википедии:

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

Я считаю, что этот "обратный вызов" жаргон был ошибочно использован во многих местах. Мое определение будет примерно таким:

Функция обратного вызова - это функция, которую вы передаете кому-то и позволяете они называют это в некоторый момент времени.

Я думаю, что люди просто прочитали первое предложение определения wiki:

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

Я работаю с большим количеством API-интерфейсов, вижу различные плохие примеры. Многие люди имеют тенденцию называть указатель на функцию (ссылку на исполняемый код) или анонимные функции (часть исполняемого кода) "обратный вызов", если они являются просто функциями, для чего вам нужно другое имя для этого?

Фактически только второе предложение в определении wiki показывает различия между функцией обратного вызова и нормальной функцией:

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

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

Я надеюсь, что люди могут перестать использовать это слово в неоднозначном контексте, это не может помочь людям лучше понять только хуже.

Ответ 7

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

- Пол Якубик, "Репликация обратного вызова в С++"

Ответ 8

Пусть будет проще. Что такое функция обратного вызова?

Пример по притче и аналогии

У меня есть секретарь. Каждый день я прошу ее: (i) отвезти фирменную исходящую почту на почту, и после того, как она это сделает, выполнить: (ii) любую задачу, которую я написал для нее на одной из этих записок.

Теперь, что является задачей на заметку? Задача меняется день ото дня.

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

В итоге:

  1. во-первых, ей нужно отправить письмо и
  2. сразу после этого ей нужно распечатать некоторые документы.

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

Давай теперь свяжем это с лексикой программирования

  • Имя метода в этом случае: DropOffMail.
  • И функция обратного вызова: PrintOffDocuments. PrintOffDocuments - это функция обратного вызова, потому что мы хотим, чтобы секретарь делал это только после запуска DropOffMail.
  • Поэтому я бы "передал: PrintOffDocuments в качестве" аргумента "методу DropOffMail. Это важный момент.

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

Ответ 9

Это делает обратные вызовы звуковыми выражениями возврата в конце методов.

Я не уверен, что они есть.

Я думаю, что обратные вызовы на самом деле являются вызовом функции, как следствие вызова и завершения другой функции.

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

Ответ 10

Вызов будет лучшим именем, чем глупое имя, callback. Когда или когда условие встречается внутри функции, вызовите другую функцию, функцию Вызов после, полученную в качестве аргумента.

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

Ответ 11

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

В Javascript или, более конкретно, jQuery, например, вы можете указать аргумент обратного вызова, который будет вызываться после завершения анимации.

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

Ответ 12

Что такое обратный звонок?

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

Что такое функция обратного вызова?

  • функция обратного вызова похожа на Слугу, который "перезванивает" своему Мастеру, когда он завершил задачу.
  • функция обратного вызова - это функция, которая передается другой функции (пусть эта другая функция 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 обратный вызов позволяет подключаемым модулям получать доступ к сервисам из контейнера/среды.

Аналогия: обратные вызовы. Асинхронный. Неблокируемая
Пример из реальной жизни для обратного вызова

Ответ 13

Посмотрите на изображение:) this is how it works

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

Наконец, функция библиотеки вызывает функцию обратного вызова во время выполнения.

Ответ 14

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

Ответ 15

Предположим, что мы имеем функцию 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)`   ...

Это концепция, используемая для достижения полиморфизма в объектно-ориентированном программировании

Ответ 16

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

Обратный вызов в C с использованием указателя функции

В C обратный вызов реализуется с помощью Function Pointer. Указатель функций - как следует из названия, является указателем на функцию.

Например, 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 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);
}

Caller или класс более высокого уровня

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);
}
}

Как видно из приведенного выше кода, у нас есть интерфейс, называемый событиями, который в основном перечисляет все события, которые могут произойти для нашего приложения. Класс Widget является базовым классом для всех компонентов пользовательского интерфейса, таких как Button, Checkbox. Эти компоненты пользовательского интерфейса являются объектами, которые фактически получают события из кода структуры. Класс Widget реализует интерфейс Events, а также имеет два вложенных интерфейса: OnClickEventListener и OnLongClickEventListener

Эти два интерфейса отвечают за прослушивание событий, которые могут возникнуть в компонентах пользовательского интерфейса Widget, например Button или Checkbox. Поэтому, если мы сравним этот пример с предыдущим примером обратного вызова с использованием интерфейса Java, эти два интерфейса работают как интерфейс обратного вызова. Таким образом, код более высокого уровня (здесь Activity) реализует эти два интерфейса. И всякий раз, когда событие возникает с виджетами, вызывается код более высокого уровня (или метод этих интерфейсов, реализованный в коде более высокого уровня, который является здесь Activity).

Теперь позвольте мне обсудить основное различие между обратным вызовом и шаблоном Eventlistener. Как мы уже упоминали, используя Callback, Callee может уведомлять только одного Caller. Но в случае шаблона EventListener любая другая часть или класс приложения может регистрироваться для событий, которые могут возникнуть на кнопке или флажке. Примером такого класса является OtherClass. Если вы видите код OtherClass, вы обнаружите, что он зарегистрировался как прослушиватель ClickEvent, который может возникнуть в Button, определенной в Activity. Интересная часть состоит в том, что помимо Activity (Caller) этот OtherClass также будет уведомлен о каждом событии click на Button.

Ответ 17

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

  • уведомление о завершении задачи
  • запрашивая сравнение между двумя элементами (например, в c qsort())
  • сообщать о ходе процесса
  • уведомление о событиях
  • делегирование instanciation объекта
  • делегирование картины области

...

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

Ответ 18

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

Ответ 19

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

$("#button_1").click(function() {
  alert("button 1 Clicked");
});

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

Ответ 20

Функция обратного вызова Функция, переданная другой функции в качестве аргумента.

function test_function(){       
 alert("Hello world");  
} 

setTimeout(test_function, 2000);

Примечание. В приведенном выше примере test_function используется в качестве аргумента для функции setTimeout.

Ответ 21

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

Ответ 22

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

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

"Что заставило их (компьютерных ученых) разработать обратный вызов?" Вы можете узнать проблему, которая блокирует (особенно блокирует пользовательский интерфейс), и обратный вызов не является единственным решением. Есть много других решений (например: Thread, Futures, Promises...).