HTML / CSSJavaScriptNode jsПаттерны проектированияПрактические

Callback

Что такое callback-функции?

Простое определение: колбэк это функция, которая выполнится после другой функции, завершившей своё выполнение. Следовательно, отсюда и название, ‘call back’. Определение посложнее: В JavaScript, функции это объекты. Поэтому, функции, могут брать другие функции в виде аргументов и также могут быть возвращены другими функциями. Функции которые так делают, называются функциями высшего порядка. Любая функция, которая передается как аргумент — именуется callback-функцией.

Для чего ? 🤔

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

1function first(){
2 console.log(1);
3}
4function second(){
5 console.log(2);
6}
7first();
8second();
9/**
10* Как вы и ожидаете, функция first выполнится первой, а функция second после нее, и в консоли будет выведен следующий результат:
11*
12*/
13
14//output: 1
15//output: 2

Пока что все понятно. Но что если функция first содержит некий код, который не может выполниться немедленно? К примеру, запрос к API, где мы отправляем запрос и должны ждать ответа. Чтобы смоделировать такую ситуацию, мы используем функцию setTimeout, которая вызывает функцию после заданного временного промежутка. Мы отсрочим выполнение функции на 500 миллисекунд, как будто бы это запрос к некому API. Теперь код будет выглядеть так:

1function first(){
2 // Как будто бы запрос к API
3 setTimeout( function(){
4 console.log(1);
5 }, 500 );
6}
7function second(){
8 console.log(2);
9}
10first();
11second();

Неважно, понимаете ли вы сейчас, как работает setTimeout(). Основная идея — теперь мы отложили исполнение команды console.log(1) на 500 миллисекунд. И что теперь выведет наша программа?

1first();
2second();
3// 2
4// 1

Хотя мы по-прежнему вызываем функцию first первой, ее вывод появился вторым, после вывода функции second. Но JavaScript не нарушает порядок вызова функций, он просто не дожидается ответа от функции first, а сразу двигается дальше — к функции second.

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

Создадим свой собственный callback

1function doHomework(subject) {
2 console.log(`Starting my ${subject} homework.`);
3}

Наша функция принимает одну переменную — название предмета, которым мы будем заниматься. Вызовите функцию, набрав следующий текст в консоли:

1doHomework('math');
2// Выводит console: Starting my math homework.

Теперь давайте добавим в определение функции еще один параметр, это и будет наш коллбэк. Затем вызовем ее, определив функцию-callback в качестве аргумента:

1function doHomework(subject, callback) {
2console.log(`Starting my ${subject} homework.`);
3callback();
4}
5
6doHomework('math', function() {
7console.log('Finished my homework');
8});

Если выполнить этот код в консоли, получим 2 console.log один за другим, в первом будет сообщение о том, что выполнение домашнего задания началось (Starting my math homework.), а во втором — что вы закончили выполнять задание (Finished my homework).

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

1function doHomework(subject, callback) {
2 console.log(`Starting my ${subject} homework.`);
3 callback();
4}
5function alertFinished(){
6 console.log('Finished my homework');
7}
8doHomework('math', alertFinished);

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

Практика 👩‍💻 👨‍💻

Задание 1

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

1function fnWithCallback(cb) {}

Задание 2

Написать свою реализацию Array.map

1function mapArray(arr, cb) {}

Задание 3

1function filterArray(arr, cb) {}

Написать свою реализацию Array.filter

Проверить правильность задание можно использовать sandbox если все три функции будут реализованы правильно Все Test Suites должны быть зеленые ✅

Original source
Hello