Колбэки
Раз функция — это значение, её можно передать в другую функцию как аргумент. Функцию, которую передают, чтобы её вызвали позже, называют колбэком (от англ. callback — «обратный вызов»). Колбэки встречаются повсюду: в методах массивов, обработчиках нажатий, таймерах.
Передача функции
Функцию передают по имени, без скобок. Внутри принимающей функции её вызывают через параметр, как обычную функцию:
function sayHello() {
console.log('Привет!'); // Привет!
}
function run(callback) {
callback();
}
run(sayHello);Функция run не знает, что именно делает колбэк, — она просто вызывает то, что ей передали.
Колбэк с аргументами
Принимающая функция может передать колбэку данные. Так одна функция решает, когда выполнить действие, а колбэк — что именно сделать:
function repeat(times, action) {
for (let i = 1; i <= times; i++) {
action(i);
}
}
repeat(3, (n) => console.log(`Повтор ${n}`));
// Повтор 1
// Повтор 2
// Повтор 3Стрелочная функция на месте
Колбэк не обязательно объявлять заранее. Чаще всего его пишут прямо в вызове — короткой стрелочной функцией, как в примере выше. Отдельное имя нужно, только если колбэк длинный или используется в нескольких местах.
function calculate(a, b, operation) {
return operation(a, b);
}
console.log(calculate(6, 3, (x, y) => x + y)); // 9
console.log(calculate(6, 3, (x, y) => x * y)); // 18Одна функция calculate выполняет разные действия в зависимости от колбэка.
Колбэки в методах массивов
Встроенные методы массивов принимают колбэк и вызывают его для каждого элемента. Например, map() создаёт новый массив из результатов колбэка, а filter() оставляет элементы, для которых колбэк вернул true:
const prices = [10, 25, 40];
console.log(prices.map((p) => p * 2).join(', ')); // 20, 50, 80
console.log(prices.filter((p) => p > 20).join(', ')); // 25, 40Подробно эти методы разберём в главе о массивах.
Колбэки и время
Колбэк позволяет отложить действие: функция вызовет его не сразу, а когда что-то произойдёт — пройдёт время, пользователь нажмёт кнопку или придут данные с сервера. Например, setTimeout(callback, 1000) вызовет колбэк через секунду. Таймеры и события подробно разберём в главах об асинхронности и DOM.
Частая ошибка
Если поставить после имени колбэка скобки, функция выполнится сразу, а в принимающую функцию попадёт её результат, а не она сама:
function getGreeting() {
return 'Привет!';
}
function run(callback) {
return typeof callback;
}
console.log(run(getGreeting)); // function
console.log(run(getGreeting())); // stringПередавайте функцию без скобок: run(getGreeting). Вызывать её будет та функция, которая её получила.