Колбэк-функция
Колбэк-функция (или обратный вызов) — это функция, переданная в другую функцию в качестве аргумента, которая затем вызывается по завершению какого-либо действия.
Вот краткий пример:
function greeting(name) alert("Hello " + name); > function processUserInput(callback) var name = prompt("Please enter your name."); callback(name); > processUserInput(greeting);
Выше приведён пример синхронного колбэка, поскольку функция processUserInput выполняется синхронно.
Колбэки часто используются для продолжения выполнения кода после завершения асинхронной операции — они называются асинхронными колбэками.
async function pageLoader(callback) const data = await fetch("/ru/docs/Glossary/Callback_function"); callback(data); > function onPageLoadingFinished(pageData) console.log("Page was sucessfully loaded!"); console.log("Response:"); console.log(pageData); > pageLoader(onPageLoadingFinished);
Вот ещё один пример асинхронного обратного вызова: maps-example.html (живой пример). Он использует Google Maps API и Geolocation API для отображения карты текущего местоположения вашего устройства.
// maps-example.html // Вызов асинхронной функции getCurrentPosition // с передачей callback функции принимающей координаты // в качестве параметра navigator.geolocation.getCurrentPosition(function (position) var latlng = new google.maps.LatLng( position.coords.latitude, position.coords.longitude, ); var myOptions = zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.TERRAIN, disableDefaultUI: true, >; var map = new google.maps.Map( document.getElementById("map_canvas"), myOptions, ); >);
Поскольку получение координат устройства из его GPS является асинхронным (мы точно не знаем, когда данные будут возвращены), метод Geolocation.getCurrentPosition() принимает анонимную колбэк-функцию в качестве параметра, которая получает найденные данные координат. Эта функция выполняется только по возвращению данных координат.
Больше информации
Основное
- Колбэки и события на компонентах
- Ад обратных вызовов
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
Введение в колбэк-функции в JavaScript
При изучении программирования мы привыкаем мыслить последовательно: строки кода выполняются по порядку. Для многих языков это утверждение верно на 100%, но всё начинает меняться, когда речь заходит про асинхронное программирование.
Это статья о том, как работают и зачем нужны колбэк-функции в JavaScript. Это одна из важнейших тем программирования на JavaScript, и ни одна более-менее серьёзная программа не обойдется без применения колбэк-функций.
Что такое колбэк-функция
Колбэк-функция или функция обратного вызова — функция, предназначенная для отложенного выполнения. Проще говоря, она должна быть выполнена после завершения работы другой функции. Чтобы стало понятнее, разберём пример с заказом пиццы.
Колбэк (callback) переводится как «Перезвоните». Действительно, принцип работы колбэков схож с заказом обратного телефонного звонка. Представьте, что вы звоните оператору для заказа пиццы, но срабатывает автоответчик, где приятный голос просит оставаться на линии, пока не освободится оператор, или предлагает заказать обратный звонок. Когда оператор освободится — он перезвонит и примет заказ.
Это прекрасная аналогия для понимания принципов работы колбэков и асинхронности. Вместо ожидания ответа оператора, мы можем заказать обратный звонок и заниматься другими делами. Как только произойдёт колбэк (нам перезвонили), мы сможем выполнить задуманное — заказать пиццу.
Как писать код для колбэков
Посмотрим на колбэки с практической стороны.
Выше мы сказали, что колбэки неразрывно связаны с асинхронностью и позволяют «запланировать» действие, которое будет совершено после выполнения какого-то другого, возможно длительного действия. Пример с заказом пиццы это прекрасно илюстрирует. Давайте посмотрим, как это может выглядеть в коде, но для начала взглянем на синхронный код:
// Приготовление пиццы. Длительный процесс const newPizza = makePizza('pepperoni'); // Читаем книгу пока готовят пиццу readBook(); // Съедаем пиццу eatPizza(newPizza);
Что в этом коде больше всего бросается в глаза? Правильно — последовательность. Здесь представлен синхронный код, который будет выполнятся последовательно:
- Мы ждём, пока для нас приготовят пиццу «Пепперони».
- Затем мы читаем книгу.
- Наконец-таки откладываем книгу в сторону и ужинаем пиццей.
Проблема видна невооруженным глазом — пока готовится пицца, мы вынуждены ждать и ничего не делать. Строка readBook() будет выполнена только после приготовления пиццы. Фактически мы начнём читать книгу после приготовления пиццы, а не во время готовки.
Само собой, в реальном мире вместо выпекания пиццы может быть любой долгий процесс, например, запрос на получение данных с сервера.
Такой запрос не выполняется мгновенно: браузеру понадобится время, чтобы найти IP-адрес сервера, установить соединение, передать запрос, дождаться ответа и т. д. Все эти действия занимают разное количество времени. Временные задержки будут постоянно отличаться и зависеть от скорости соединения с сетью, времени выполнения запроса на сервере и некоторых других факторов.
Синхронные запросы к серверу будут блокировать дальнейшее выполнение веб-приложения, и это уже очень плохо. Представьте, что каждый раз при отправке запроса к серверу интерфейс вашего приложения становится полностью недоступным.
Эту проблему решает асинхронность, и длительные операции лучше выполнять именно асинхронно. В этом варианте мы как бы откладываем длительную операцию «на потом» и вместо ожидания завершения выполняем другой код. В этой схеме прозрачно всё, кроме вопроса: «Как выполнить код после завершения асинхронной операции?». Ответ прост — функции обратного вызова.
В JavaScript функции являются объектами высшего порядка. Это означает, что функции можно передавать в другие функции в виде параметров или возвращать в виде результата выполнения.
const foo = function () < return 'Hello, world!'; >// Вызываем функцию и выводим результат в консоль console.log(foo()); // Hello, world // Выводим функцию в консоль без вызова console.log(foo); // ƒ ()
В первом случае мы вызываем функцию foo при помощи круглых скобок и выводим результат выполнения в консоль. Во втором примере мы не делаем вызов функции (обратите внимание на отсутствие круглых скобок), и в консоль выводится содержимое функции. Выходит, нам ничего не мешает передать функцию в виде параметра для других функций:
const runIt = function (fn) < return fn(); // Вызываем функцию, переданную в качестве параметра >console.log(runIt(foo)); // Hello, world
Мы передали функцию foo в виде параметра и вызывали её внутри функции runIt . Вызов функции мы сделали стандартным образом — применяя круглые скобки.
Что в итоге? Мы передали ссылку на функцию в виде параметра и вызвали её внутри другой функции. В этом и заключается идея колбэков: мы передаем в виде параметров функции, которые будут вызваны «когда-нибудь потом».
И снова пицца
Вернёмся к примеру с приготовлением пиццы. Попробуем поэкспериментировать с кодом и перевести его на асинхронные рельсы. Напомню, наша задача — попросить приготовить пиццу, и читать книгу, пока пицца не будет готова.
const makePizza = function (title, cb) < console.log(`Заказ на приготовление пиццы «$» получен. Начинаем готовить…`); setTimeout(cb, 3000); > const readBook = function () < console.log('Читаю книгу «Колдун и кристалл»…'); >const eatPizza = function () < console.log('Ура! Пицца готова, пора подкрепиться.'); >makePizza('Пеперонни', eatPizza); readBook();
Это рабочий код, попробуйте выполнить его в консоли и посмотреть на результат вывода. Он будет таким:
Заказ на приготовление пиццы «Пепперони» получен. Начинаем готовить… Читаю книгу «Колдун и кристалл»… // Здесь будет пауза Ура! Пицца готова, пора подкрепиться.
Функция makePizza выполняется мгновенно, и сразу за ней последовал вызов readBook . Пока мы читали книгу, приготовилась пицца, и произошёл вызов функции eatPizza из функции makePizza . Задержку выполнения мы сделали искусственно с помощью setTimeout .
Как видите, ничего сверхъестественного в колбэках нет. Это обычная функция, которая будет выполнена не сейчас, а когда-нибудь потом. «Когда-нибудь» — не преувеличение. Мы не можем сказать, в какой момент времени это случится, но можем сказать, после какой именно функции — после выполнения функции приготовлении пиццы.
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
Callback функция в JS
Функцию обратного вызова (callback) в Javascript, можно представить в реальной жизни, в виде реакции автоответчика на телефонный звонок. Ведь автоответчик обязательно ответит вам в строгой последовательности — только после полученного от вас звонка. В принципе невозможна ситуация наоборот — сначала отвечает автоответчик, а потом уже поступает ему звонок.
Как бы мы примерно записали код действия «звонок — автоответчик», без всяких коллбэков? Функция call будет звонить (соединяться с сервером и ждать от него ответа), что займет какое-то время. Вторая функция answerphone будет просто играть роль автоответчика. Затем, мы по очереди вызываем обе функции, в расчёте на то, что первой отработает функция со звонком. Так бы оно и произошло, если бы не setTimeout. Мы специально создали задержку в 500 мс. для первой функции. Зачем мы это сделали?
function call() setTimeout (function() console.log(‘Я тебе звоню’);
>, 500);
>
function answerphone () console.log(‘Оставьте ваше сообщение’);
>
В реальных программах, у разных функций (в зависимости от задач) может быть разное время выполнения. Этот пример как раз демонстрирует, что быстрее отработала вторая функция. А не должна была, ведь в коде, она стоит ниже.

Программа получилась нелогичной, совсем не так, как мы задумывали. Функция answerphone не стала ждать своей очереди и выскочила вперед, пока функция call отдыхала.
Callback функция в JS
Функция обратного вызова (callback), избавляет программу от потенциальной проблемы — отработать неправильно. Если мы хотим, чтобы в нашем коде вторая функция выполнилась бы только после первой, то следует её задать, как callback функцию. Сallback функция передается в аргументах другой функции и не начнет выполнится, пока не отработает первая функция.
Перепишем наш пример с использованием callback функции. Функция callto внутри себя будет принимать какое-то имя и callback. Мы вызываем callback внутри этой функции. При вызове функции со звонком, передадим ей два параметра: имя и callback функцию.
function callto(name, callback) console.log(‘Привет’ + ‘ ‘ + name);
callback();
>
callto(‘Alex’, function() console.log(‘После сигнала..’);
>)
На этот раз, вторая функция выполнилась, строго после выполнения первой функции. Что нам и требовалось.

Пример callback функции
На сайте расположены три блока черного цвета, необходимо все три перекрасить в розовый цвет.
Получим все элементы по селектору и присвоим этот массив переменной box. Пройдемся по всем элементам в цикле forEach. В аргументах цикла передадим анонимную callback функцию с тремя аргументами (элемент, счетчик, массив). Наша функция перекрасит цвет фона у элементов, только после того, как отработает цикл.
let box = document.querySelectorAll(‘.box’);
box.forEach(function(item, i, boxes) item.style.backgroundColor = ‘pink’;
>);
console.log(box);
Делаем проверку в консоли. У нас вывелся массив, состоящий из объектов.

Анонимная функция в JS
Анонимная функция — это функция без имени, её часто используют, как callback функцию для выполнения каких-то одноразовых действий. Например, когда функция вызывается после клика.
burgerMenu.addEventListener(‘click’, function() // тело функции
>);
Коллбэк функции гарантируют нам, что один код не начнет выполняться раньше другого кода. Что-то вроде подстраховки.

![]()
Создано 02.12.2019 10:27:48
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
- Кнопка:
Она выглядит вот так: - Текстовая ссылка:
Она выглядит вот так: Как создать свой сайт - BB-код ссылки для форумов (например, можете поставить её в подписи):
Комментарии ( 0 ):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.
Copyright © 2010-2023 Русаков Михаил Юрьевич. Все права защищены.
Что такое callback функция javascript
Callback-функции могут быть обозначены объявлением типа callable .
Некоторые функции, такие как call_user_func() или usort() , принимают определённые пользователем callback-функции в качестве параметра. Callback-функции могут быть как простыми функциями, так и методами объектов, включая статические методы классов.
Передача
В PHP функции передаются по имени в виде строки. Можно использовать любые встроенные, либо созданные пользователем функции, за исключением конструкций языка, таких как: array() , echo , empty() , eval() , exit() , isset() , list() , print или unset() .
Метод созданного объекта ( object ) передаётся как массив, содержащий объект по индексу 0 и имя метода по индексу 1. Доступ к закрытым и защищённым методам разрешён изнутри класса.
Статические методы класса также могут быть вызваны без создания экземпляра объекта класса путём передачи имени класса вместо объекта в элементе массива с индексом 0 или выполнения ‘ClassName::methodName’ .
Помимо обычных пользовательских функций, в качестве callback-функции можно передавать анонимные функции и стрелочные функции.
Замечание:
Начиная с PHP 8.1.0, у Callback-функций как объектов первого класса та же семантика, что и у этого метода.
Как правило, любой объект, реализующий __invoke(), также может быть передан в параметр callback.
Пример #1 Пример callback-функции
// Пример callback-функции
function my_callback_function () echo ‘Привет, мир!’ ;
>
// Пример callback-метода
class MyClass static function myCallbackMethod () echo ‘Привет, мир!’ ;
>
>
// Тип 1: Простой callback
call_user_func ( ‘my_callback_function’ );
// Тип 2: Вызов статического метода класса
call_user_func (array( ‘MyClass’ , ‘myCallbackMethod’ ));
// Тип 3: Вызов метода класса
$obj = new MyClass ();
call_user_func (array( $obj , ‘myCallbackMethod’ ));
// Тип 4: Вызов статического метода класса
call_user_func ( ‘MyClass::myCallbackMethod’ );
// Тип 5: Вызов относительного статического метода
class A public static function who () echo «A\n» ;
>
>
class B extends A public static function who () echo «B\n» ;
>
>
call_user_func (array( ‘B’ , ‘parent::who’ )); // A, устарело, начиная с PHP 8.2.0
// Тип 6: Объекты, реализующие __invoke, могут быть использованы как callback
class C public function __invoke ( $name ) echo ‘Привет ‘ , $name , «\n» ;
>
>
$c = new C ();
call_user_func ( $c , ‘PHP!’ );
?>
Пример #2 Пример callback-функции с использованием замыкания
// Наше замыкание
$double = function( $a ) return $a * 2 ;
>;
?php
// Диапазон чисел
$numbers = range ( 1 , 5 );
// Использование замыкания в качестве callback-функции
// для удвоения каждого элемента в нашем диапазоне
$new_numbers = array_map ( $double , $numbers );
print implode ( ‘ ‘ , $new_numbers );
?>
Результат выполнения данного примера:
2 4 6 8 10
Замечание:
Callback-функции, зарегистрированные такими функциями как call_user_func() и call_user_func_array() , не будут вызваны при наличии не пойманного исключения, брошенного в предыдущей callback-функции.
User Contributed Notes 19 notes
11 years ago
You can also use the $this variable to specify a callback:
public $property = ‘Hello World!’ ;
public function MyMethod ()
<
call_user_func (array( $this , ‘myCallbackMethod’ ));
>
public function MyCallbackMethod ()
<
echo $this -> property ;
>
11 years ago
Performance note: The callable type hint, like is_callable(), will trigger an autoload of the class if the value looks like a static method callback.
10 years ago
When specifying a call back in array notation (ie. array($this, «myfunc») ) the method can be private if called from inside the class, but if you call it from outside you’ll get a warning:
class mc <
public function go (array $arr ) <
array_walk ( $arr , array( $this , «walkIt» ));
>
private function walkIt ( $val ) <
echo $val . «
» ;
>
public function export () <
return array( $this , ‘walkIt’ );
>
>
$data = array( 1 , 2 , 3 , 4 );
$m = new mc ;
$m -> go ( $data ); // valid
array_walk ( $data , $m -> export ()); // will generate warning
?>
Output:
1
2
3
4
Warning: array_walk() expects parameter 2 to be a valid callback, cannot access private method mc::walkIt() in /in/tfh7f on line 22
8 years ago
A note on differences when calling callbacks as «variable functions» without the use of call_user_func() (e.g. » «):
?php>
— Using the name of a function as string has worked since at least 4.3.0
— Calling anonymous functions and invokable objects has worked since 5.3.0
— Using the array structure [$object, ‘method’] has worked since 5.4.0
Note, however, that the following are not supported when calling callbacks as variable functions, even though they are supported by call_user_func():
— Calling static class methods via strings such as ‘foo::doStuff’
— Calling parent method using the [$object, ‘parent::method’] array structure
All of these cases are correctly recognized as callbacks by the ‘callable’ type hint, however. Thus, the following code will produce an error «Fatal error: Call to undefined function foo::doStuff() in /tmp/code.php on line 4»:
class foo static function callIt (callable $callback ) $callback ();
>
static function doStuff () echo «Hello World!» ;
>
>
foo :: callIt ( ‘foo::doStuff’ );
?>
The code would work fine, if we replaced the ‘$callback()’ with ‘call_user_func($callback)’ or if we used the array [‘foo’, ‘doStuff’] as the callback instead.
8 years ago
You can use ‘self::methodName’ as a callable, but this is dangerous. Consider this example:
class Foo public static function doAwesomeThings () FunctionCaller :: callIt ( ‘self::someAwesomeMethod’ );
>
public static function someAwesomeMethod () // fantastic code goes here.
>
>
class FunctionCaller public static function callIt (callable $func ) call_user_func ( $func );
>
>
Foo :: doAwesomeThings ();
?>
This results in an error:
Warning: class ‘FunctionCaller’ does not have a method ‘someAwesomeMethod’.
For this reason you should always use the full class name:
FunctionCaller :: callIt ( ‘Foo::someAwesomeMethod’ );
?>
I believe this is because there is no way for FunctionCaller to know that the string ‘self’ at one point referred to to `Foo`.
10 years ago
you can pass an object as a callable if its class defines the __invoke() magic method..
9 years ago
> As of PHP 5.2.3, it is also possible to pass ‘ClassName::methodName’
You can also use ‘self::methodName’. This works in PHP 5.2.12 for me.
8 years ago
I needed a function that would determine the type of callable being passed, and, eventually,
normalized it to some extent. Here’s what I came up with:
/**
* The callable types and normalizations are given in the table below:
*
* Callable | Normalization | Type
* ———————————+———————————+—————
* function (. ) use (. ) <. >| function (. ) use (. ) <. >| ‘closure’
* $object | $object | ‘invocable’
* «function» | «function» | ‘function’
* «class::method» | [«class», «method»] | ‘static’
* [«class», «parent::method»] | [«parent of class», «method»] | ‘static’
* [«class», «self::method»] | [«class», «method»] | ‘static’
* [«class», «method»] | [«class», «method»] | ‘static’
* [$object, «parent::method»] | [$object, «parent::method»] | ‘object’
* [$object, «self::method»] | [$object, «method»] | ‘object’
* [$object, «method»] | [$object, «method»] | ‘object’
* ———————————+———————————+—————
* other callable | idem | ‘unknown’
* ———————————+———————————+—————
* not a callable | null | false
*
* If the «strict» parameter is set to true, additional checks are
* performed, in particular:
* — when a callable string of the form «class::method» or a callable array
* of the form [«class», «method»] is given, the method must be a static one,
* — when a callable array of the form [$object, «method»] is given, the
* method must be a non-static one.
*
*/
function callableType ( $callable , $strict = true , callable& $norm = null ) if (! is_callable ( $callable )) switch ( true ) case is_object ( $callable ):
$norm = $callable ;
return ‘Closure’ === get_class ( $callable ) ? ‘closure’ : ‘invocable’ ;
case is_string ( $callable ):
$m = null ;
if ( preg_match ( ‘~^(?[a-z_][a-z0-9_]*)::(?[a-z_][a-z0-9_]*)$~i’ , $callable , $m )) list( $left , $right ) = [ $m [ ‘class’ ], $m [ ‘method’ ]];
if (! $strict || (new \ReflectionMethod ( $left , $right ))-> isStatic ()) $norm = [ $left , $right ];
return ‘static’ ;
>
> else $norm = $callable ;
return ‘function’ ;
>
break;
case is_array ( $callable ):
$m = null ;
if ( preg_match ( ‘~^(:?(?self|parent)::)?(?[a-z_][a-z0-9_]*)$~i’ , $callable [ 1 ], $m )) if ( is_string ( $callable [ 0 ])) if ( ‘parent’ === strtolower ( $m [ ‘reference’ ])) list( $left , $right ) = [ get_parent_class ( $callable [ 0 ]), $m [ ‘method’ ]];
> else list( $left , $right ) = [ $callable [ 0 ], $m [ ‘method’ ]];
>
if (! $strict || (new \ReflectionMethod ( $left , $right ))-> isStatic ()) $norm = [ $left , $right ];
return ‘static’ ;
>
> else if ( ‘self’ === strtolower ( $m [ ‘reference’ ])) list( $left , $right ) = [ $callable [ 0 ], $m [ ‘method’ ]];
> else list( $left , $right ) = $callable ;
>
if (! $strict || !(new \ReflectionMethod ( $left , $right ))-> isStatic ()) $norm = [ $left , $right ];
return ‘object’ ;
>
>
>
break;
>
$norm = $callable ;
return ‘unknown’ ;
>
$norm = null ;
return false ;
>
?>
Hope someone else finds it useful.
