Автор: Нилеш Саньял
Перевод: сумасшедший технический ботаник
оригинал:D zone.com/articles/Спешите…
Копирование без разрешения строго запрещено
Обратный вызов JavaScriptФункции — важная концепция, которую нужно понимать, чтобы стать успешным разработчиком JavaScript. Но я верю, что после прочтения этой статьи вы сможете преодолеть все препятствия, с которыми сталкивались перед использованием методов обратного вызова.
Прежде чем мы начнем, давайте сначала убедимся, что наше понимание функций прочно.
Краткий обзор: функции JavaScript
Что такое функция?
Функция — это логический строительный блок с набором кода для выполнения конкретной задачи. На самом деле, для простоты отладки и обслуживания функции позволяют писать код более организованно. Функции также позволяют повторно использовать код.
Вместо того, чтобы писать один и тот же код снова и снова, вы определяете функцию один раз и вызываете ее при необходимости.
объявить функцию
Теперь давайте посмотрим, как объявить функцию в javascript.
-
Используйте конструктор функции:В этом подходе функции создаются с помощью конструктора «функция». Технически этот метод менее эффективен, чем использование синтаксиса выражения функции и синтаксиса объявления функции для объявления функций.
-
Используйте функциональные выражения:Этот метод, как правило, аналогичен присваиванию переменной. Короче говоря, тело функции считается выражением, а выражение присваивается переменной. Использование определений синтаксиса функции может быть именованной функцией или анонимной функцией.
Функция без имени называется анонимной функцией. Анонимная функция является самовызывающейся, то есть автоматически вызывает сама себя. Такое поведение также известно как немедленно вызываемое функциональное выражение (IIFE).
-
Используйте объявление функции:Этот подход является подходом старой школы, обычно используемым в JavaScript. После ключевого слова «функция» необходимо указать имя функции. После этого, если функция принимает несколько аргументов или аргументов, их тоже нужно упомянуть. Хотя эта часть совершенно необязательна.
В теле функции функция должна возвращать значение вызывающей стороне. После встречи с оператором return функция перестанет выполняться. Внутри функции параметры будут действовать как локальные переменные.
Точно так же переменные, объявленные внутри функции, являются локальными для этой функции. Локальные переменные доступны только внутри этой функции, поэтому переменные с одинаковыми именами можно легко использовать в разных функциях.
вызвать функцию
Объявленная ранее функция будет вызываться в любом из следующих случаев:
-
Когда происходит событие, например, пользователь нажимает кнопку, или пользователь выбирает какую-то опцию из выпадающего списка и т. д.
-
При вызове функции из кода javascript.
-
Функция может быть вызвана автоматически, что мы обсуждали в выражениях анонимных функций.
()
оператор для вызова функции.
Что такое функция обратного вызова?
Как описано MDN:Функция обратного вызова — это функция, которая передается в качестве параметра другой функции, а затем вызывает функцию обратного вызова внутри внешней функции для выполнения некоторого действия..
Позвольте мне объяснить человеческими терминами, функция обратного вызова — это функция, которая будет выполняться, как только завершится выполнение другой функции. Функция обратного вызова — это функция, которая передается в качестве аргумента другой функции JavaScript. Эта функция обратного вызова будет выполняться внутри переданной функции.
Функции в JavaScript рассматриваются как объекты первого класса. Под классом объектов мы подразумеваем, что числа, функции или переменные могут быть такими же, как и другие объекты языка. Как объект первого класса, функции могут быть переданы в качестве переменных другим функциям, и эти функции могут быть возвращены из других функций.
Функции, которые могут это сделать, называются функциями высшего порядка. Функция обратного вызова на самом деле является шаблоном. Слово «шаблон» относится к какому-то проверенному методу решения распространенных проблем при разработке программного обеспечения. В качестве режима обратного вызова лучше использовать функцию обратного вызова.
Зачем нужны обратные вызовы
Клиентский JavaScriptЗапускается в браузере, а основной процесс браузера является однопоточным.цикл событий. Если мы попытаемся выполнить длительную операцию в однопоточном цикле событий, процесс будет заблокирован. Технически это плохо, потому что процесс перестает обрабатывать другие события, ожидая завершения операции.
Например,alert
оператор считается одним из кодов блокировки в javascript в браузерах. Если вы запустите оповещение, вы не сможете выполнять какие-либо действия в браузере, пока диалоговое окно оповещения не будет закрыто. Чтобы предотвратить блокировку длительных операций, мы используем обратные вызовы.
Давайте копнем немного глубже, чтобы дать вам представление о том, где именно использовать обратные вызовы.
В приведенном выше фрагменте кода сначала выполнитеgetMessage()
Функция, затем выполнениеdisplayMessage()
. Оба отображают сообщение в окне консоли браузера и оба выполняются немедленно.
В некоторых случаях некоторый код выполняется не сразу. Например, если мы предположимgetMessage()
функция делает вызов API, вы должны отправить запрос на сервер и дождаться ответа. Как нам быть с этим?
Как использовать функции обратного вызова
Я думаю, вместо того, чтобы рассказывать вам синтаксис функции обратного вызова JavaScript, лучше реализовать функцию обратного вызова в предыдущем примере. Измененный фрагмент кода показан на скриншоте ниже.
Чтобы использовать функцию обратного вызова, нам нужно выполнить какую-то задачу без немедленных результатов. Чтобы имитировать это поведение, мы используем JavaScriptsetTimeout()
функция. Функция делает паузу на две секунды, а затем отображает сообщение «Привет, там» в окне консоли.
«Отображаемое сообщение» будет отображаться в окне консоли браузера. В этом случае сначала нужно подождатьgetMessage()
функция. После успешного выполнения этой функции выполнитеdisplayMessage()
функция.
Как работают обратные вызовы
Позвольте мне объяснить, что происходит за кулисами в предыдущем примере.
Как видно из предыдущего примера, вgetMessage()
В функцию мы передаем два параметра. Первый параметрmsg
переменная, которая отображается в окне консоли браузера, а вторым параметром является функция обратного вызова.
Теперь вам может быть интересно, почему обратные вызовы передаются в качестве аргументов — чтобы реализовать обратные вызовы, мы должны передать функцию в качестве аргумента другой функции.
существуетgetMessage()
После выполнения задачи вызовем callback-функцию. После этого при вызовеgetMessage()
функцию, передайте ссылку наdisplayMessage()
функция, которая является функцией обратного вызова.
Обратите внимание, что при звонкеgetMessage()
функции, мы просто передаем ее ссылку наdisplayMessage()
функция. Вот почему вы не видите рядом с ним оператора вызова функции, т.е.()
символ.
Являются ли обратные вызовы Javascript асинхронными?
JavaScript считается однопоточным языком сценариев. Однопоточный — это когда JavaScript выполняет один блок кода за раз. Когда JavaScript занят выполнением одного блока, невозможно перейти к следующему блоку.
Другими словами, мы можем думать, что код JavaScript по своей природе всегда блокирует. Но эта блокирующая природа не позволяет нам писать код в некоторых случаях, когда у нас нет возможности получить результат сразу после выполнения какой-то конкретной задачи.
В число задач, о которых я говорю, входят следующие:
- Данные извлекаются путем выполнения вызовов API к определенным конечным точкам.
- Получите некоторый ресурс (например, текстовый файл, файл изображения, двоичный файл и т. д.) с удаленного сервера, отправив сетевой запрос.
Чтобы справиться с такими ситуациями, вы должны написать асинхронный код, и функции обратного вызова — это один из способов справиться с такими ситуациями. Таким образом, функция обратного вызова является асинхронной.
Ад обратного вызова Javascript
Ад обратного вызова возникает, когда несколько асинхронных функций выполняются одна за другой. Он также известен как Пирамида Судьбы.
Предположим, вы хотите получить список всех пользователей Github. Затем пользователи ищут основных участников библиотеки JavaScript. Опять же, вы хотите получить информацию о человеке по имени Джон в пользователе.
Для реализации этого функционала с помощью обратных вызовов код должен выглядеть так:
http.get('https://api.github.com/users', function(users) {
/* Display all users */
console.log(users);
http.get('https://api.github.com/repos/javascript/contributors?q=contributions&order=desc', function(contributors) {
/* Display all top contributors */
console.log(contributors);
http.get('https://api.github.com/users/Jhon', function(userData) {
/* Display user with username 'Jhon' */
console.log(userData);
});
});
});
Из приведенного выше фрагмента кода видно, что код становится труднее понять, а также сложнее поддерживать и модифицировать. Это вызвано вложенностью функций обратного вызова.
Как избежать ада обратного вызова?
Есть несколько методов, которые можно использовать, чтобы избежать ада обратного вызова, а именно:
- использовать промисы
- С асинхронным ожиданием
- Используйте библиотеку async.js
Использование библиотеки Async.js
Давайте поговорим о том, как избежать ада обратных вызовов с помощью библиотеки async.js.
Согласно описанию официального сайта async.js:Async — это служебный модуль, предоставляющий простые и мощные функции для работы с асинхронным JavaScript..
Всего Async.js предоставляет около 70 функций. Сейчас мы обсудим только два из них, а именноasync.waterfall()
иasync.series()
.
async.waterfall()
Эта функция полезна, когда вы хотите запускать определенные задачи одну за другой, а затем передавать результаты предыдущей задачи следующей. Он принимает массив функций «задачи» и последнюю функцию «обратного вызова», которая будет вызываться после завершения всех функций в массиве «задачи» или после вызова «обратного вызова» с объектом ошибки.
var async = require('async');
async.waterfall([
function(callback) {
/*
Here, the first argument value is null, it indicates that
the next function will be executed from the array of functions.
If the value was true or any string then final callback function
will be executed, other remaining functions in the array
will not be executed.
*/
callback(null, 'one', 'two');
},
function(param1, param2, callback) {
// param1 now equals 'one' and param2 now equals 'two'
callback(null, 'three');
},
function(param1, callback) {
// param1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
/*
This is the final callback function.
result now equals 'done'
*/
});
async.series()
Это полезно, когда вы хотите запустить функцию, а затем получить результат после успешного выполнения всех функций.async.waterfall()
иasync.series()
Основное различие между ними заключается в том, чтоasync.series()
Никакие данные не передаются из одной функции в другую.
async.series([
function(callback) {
// do some stuff ...
callback(null, 'one');
},
function(callback) {
// do some more stuff ...
callback(null, 'two');
}
],
// optional callback
function(err, results) {
// results is now equal to ['one', 'two']
});
Обратные вызовы и закрытия Javascript
Закрытие
С технической точки зрения замыкание представляет собой комбинацию функций, связанных вместе, ссылающихся на состояние вокруг него.
В двух словах, замыкания позволяют получить доступ к области действия внешней функции из внутренней функции.
Чтобы использовать замыкания, нам нужно определить функцию внутри другой функции. Затем нам нужно вернуть или передать его другой функции.
Перезвони
Концептуально обратные вызовы аналогичны замыканиям. Обратные вызовы — это в основном использование одной функции в качестве другой функции.
последние слова
Надеюсь, эта статья рассеет все ваши сомнения по поводу функций обратного вызова javascript. Если вы нашли эту статью полезной, пожалуйста, поделитесь ею с другими.