Статьи

Назад к основам: что такое обратные вызовы в JavaScript?

При изучении JavaScript, это не займет много времени, пока вы не столкнетесь с обратными вызовами. Это может показаться странным и загадочным для начинающих, но очень важно понять, как они работают, чтобы использовать силу языка. В этой статье я научу вас основам обратных вызовов на простых для понимания примерах.

Назад к основам: что такое обратные вызовы в JavaScript?

Callbacks — изображение через unsplash

Что такое обратный звонок?

Проще говоря: обратный вызов — это функция, которая должна выполняться после завершения выполнения другой функции (обычно асинхронной) — отсюда и название «обратный вызов».

Более сложный: в JavaScript функции — это объекты. Из-за этого функции могут принимать функции в качестве аргументов и могут быть возвращены другими функциями. Функции, которые делают это, называются функциями высшего порядка. Любая функция, которая передается в качестве аргумента и впоследствии вызывается функцией, которая ее получает, называется функцией обратного вызова.

Это много слов. Давайте посмотрим на некоторые примеры, чтобы разбить это немного подробнее.

Эта статья была впервые опубликована на codeburst.io и опубликована здесь с разрешения автора. Если вам нравится читать, почему бы не зайти туда и не посмотреть другие статьи Брэндона ? Если вы хотите улучшить свои навыки работы с JavaScript в целом, почему бы не перейти на SitePoint Premium и записаться на наш курс Введение в JavaScript .

Зачем нам нужны обратные вызовы?

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

function first(){ console.log(1); } function second(){ console.log(2); } first(); second(); 

Как и следовало ожидать, функция first выполняется первой, а функция second выполняется второй — запись в консоль следующего:

 // 1 // 2 

Пока все хорошо.

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

 function first(){ // Simulate a code delay setTimeout( function(){ console.log(1); }, 500 ); } function second(){ console.log(2); } first(); second(); 

Не важно, что вы понимаете, как setTimeout() работает сейчас (хотя, если вам интересно, у нас есть учебник по этой теме ). Все, что имеет значение, это то, что вы видите, что мы перенесли наш console.log(1); внутри нашей задержки 500 миллисекунд. Так что же происходит сейчас, когда мы вызываем наши функции?

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

Несмотря на то, что мы first() вызвали функцию first() , мы вышли из результатов этой функции после функции second() .

Дело не в том, что JavaScript не выполнял наши функции в том порядке, в котором мы этого хотели, а в том, что JavaScript не ждал ответа от first() прежде чем перейти к выполнению second ().

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

Создать обратный звонок

Хорошо, достаточно разговоров, давайте создадим обратный вызов!

Сначала откройте консоль разработчика браузера (это можно сделать, нажав Ctrl + Shift + J в Windows / Linux или Cmd + Option + J в Mac). Затем введите следующее объявление функции в вашей консоли:

 function doHomework(subject) { alert(`Starting my ${subject} homework.`); } 

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

 doHomework('math'); // Alerts: Starting my math homework. 

Теперь давайте добавим наш обратный вызов — в качестве нашего последнего параметра в функции doHomework() мы можем передать обратный вызов. Затем функция обратного вызова определяется во втором аргументе нашего вызова doHomework() .

 function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } doHomework('math', function() { alert('Finished my homework'); }); 

Попробуйте этот пример на JS Bin

Как вы увидите, если вы введете приведенный выше код в вашу консоль, вы получите два предупреждения подряд: ваше предупреждение «Начало домашней работы», а затем предупреждение «Готовая домашняя работа».

Но функции обратного вызова не всегда должны быть определены в нашем вызове функции. Они могут быть определены в другом месте нашего кода следующим образом:

 function doHomework(subject, callback) { alert(`Starting my ${subject} homework.`); callback(); } function alertFinished(){ alert('Finished my homework'); } doHomework('math', alertFinished); 

Попробуйте этот пример на JS Bin:

Этот результат этого примера точно такой же, как и в предыдущем примере, но настройка немного отличается. Как вы можете видеть, мы передали определение функции alertFinished в качестве аргумента во время doHomework() функции doHomework() !

Пример из реального мира

На прошлой неделе я опубликовал статью о том, как создать бота в Twitter из 38 строк кода . Единственная причина, по которой код в этой статье работает, заключается в API Twitter. Когда вы отправляете запросы в API, вам нужно дождаться ответа, прежде чем вы сможете действовать по этому ответу. Это замечательный пример реального использования сценариев для обратных вызовов. Вот как выглядит запрос:

 T.get('search/tweets', params, function(err, data, response) { if(!err){ // This is where the magic will happen } else { console.log(err); } }); 
  • T.get просто означает, что мы делаем запрос GET в Twitter.
  • В этом запросе есть три параметра: 'search/tweets' , который является маршрутом нашего запроса, params которые являются нашими параметрами поиска, и затем анонимная функция, которая является нашим обратным вызовом.

Обратный вызов важен здесь, потому что нам нужно дождаться ответа от сервера, прежде чем мы сможем двигаться дальше в нашем коде. Мы не знаем, будет ли наш запрос API успешным или нет, после отправки наших параметров для search/tweets помощью запроса GET мы ждем. Когда Twitter отвечает, вызывается наша функция обратного вызова. Twitter отправит нам объект err (error) или объект response . В нашей функции обратного вызова мы можем использовать оператор if() чтобы определить, был ли наш запрос успешным, или нет, а затем действовать соответственно с новыми данными.

Ты сделал это

Хорошая работа! Теперь вы можете понять, что такое обратный вызов и как он работает. Но это всего лишь верхушка айсберга с обратными вызовами, еще многое предстоит узнать! Если у вас есть какие-либо вопросы или комментарии, я буду рад их услышать в разделе комментариев ниже.