Понятие callback-функций в JavaScript

Понятие callback-функций в JavaScript

От автора: слово колбэк, один из сложнейших для понимания аспектов JavaScript, часто упоминается в контексте функций и событий. Что такое колбэки, и как они работают?

Вы, скорее всего, уже знакомы с колбэками. К примеру, они часто встречаются в обработчиках событий:

button.addEventListener("click", function() {
    ... какое-то действие
})

Такая callback-функция анонимна и является замыканием. На колбэки можно ссылаться через выражения функций или оберточные функции.

Зачем нужны callback-функции?

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

function first() {
    ...do something that takes a lot of calculation...
    console.log("First");
}
first();

Распечатает слово First в консоли после вычислений. Я замедлю эту функцию и создам вторую, которая будет выполняться сразу же:

function first() {
    setTimeout(function() { console.log("First"); }, 1000);
}

function second(){
    console.log("Second");
}

first();
second();

Результат в консоли будет отличаться от ожидаемого:

Second
First

Почему? В время выполнения JS находит функцию first() и исполняет ее. Затем без пауз он переходит на вторую функцию и запускает ее. JS никогда не останавливается и ищет, что ему еще выполнить. Вот почему в современных браузерах он так быстро работает.

Важно отметить, что колбэк – это всего лишь определенный способ объявления функций в JS. Явного типа callback-функций не существует. Колбэки появились в ES5 (предыдущий JS стандарт) и JQuery. На данный момент они считаются нормальной техникой программирования.

Улучшаем колбэк-функции

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

function makeMenu() {
    ... do something ...
}
button.addEventListener("click", makeMenu);

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

function makeMenu(param1) {
    console.log("Clicked");
}
button.addEventListener("click", makeMenu(param1));

Результат в консоли без события клика:

Clicked

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

function makeMenu(param1) {
    console.log("Clicked");
}
button.addEventListener("click", function() { makeMenu(param1) } );

Или же для параметров можно использовать .bind():

button.addEventListener("click", function() { makeMenu.bind(null, param1) } );

Первый пример можно сократить с помощью функции-стрелки в ES6:

button.addEventListener('click', () => makeMenu)

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

У вас может закрасться подозрение, что сцепка событий при помощи нескольких колбэк-функций может сильно усложнить код JS и запутать наследование. Вы правы. На сайте Callback Hell вы найдете парочку хороших советов по работе со сцепкой событий. В будущих статьях мы также будем уделять внимание этой проблеме.

Заключение

По существу, колбэк-функции представляют собой способ контролировать порядок выполнения кода в JS, способ добиться выполнения кода в логическом порядке. Такие функции часто называют асинхронным JS: функция передается в виде параметра и говорит «сделай это в будущем». Насколько в будущем или условия выполнения передаваемой функции описываются в колбэк-функции. В ES6 такой подход используют для промисов.

JS пронизан колбэк-функциями, которые являются неотъемлемой частью языка. window.requestAnimationFrame() – пример колбэк-функции, которая выполняется, как только браузера определяет, что он готов к отрисовке контента на экран, что обеспечивает плавность анимации.

Постоянная работа JS (всегда ждет события и мгновенно реагирует на все) также влияет на производительность, особенно в часто-запускаемых событиях типа прокрутки окна, изменения размера окна и при работе с некоторыми полями форм типа range. Я покажу эти примеры в статье, где мы будем искусственно занижать производительность браузера.

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

Источник: http://thenewcode.com/

Редакция: Команда webformyself.

Курс по JavaScript: основы

Изучите JavaScript с нуля до результата!

Смотреть курс

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree