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*/1314//output: 115//output: 2
Пока что все понятно. Но что если функция first содержит некий код, который не может выполниться немедленно? К примеру, запрос к API, где мы отправляем запрос и должны ждать ответа. Чтобы смоделировать такую ситуацию, мы используем функцию setTimeout, которая вызывает функцию после заданного временного промежутка. Мы отсрочим выполнение функции на 500 миллисекунд, как будто бы это запрос к некому API. Теперь код будет выглядеть так:
1function first(){2 // Как будто бы запрос к API3 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// 24// 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}56doHomework('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 должны быть зеленые ✅