Функции являются одним из основных строительных блоков в JavaScript. Это помогает нам выполнять конкретную задачу, когда она выполняется.

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

Давайте начнем.


Понимание функций в JavaScript

Прежде чем мы углубимся в функцию обратного вызова, давайте вернемся к function в JavaScript

А functionпредставляет собой блок кода, который выполняет определенную задачу при ее выполнении.

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

Чтобы использовать функцию, мы должны определить и вызвать ее.

Взгляните на код ниже

// define the function
function sayHi(user){

 console.log(`Hello ${user}`)
}

//callthe function
sayHi("Emmanuel")
Войти в полноэкранный режим

Выйти из полноэкранного режима

  • В приведенном выше коде мы определяем функцию, используя function ключевое слово, за которым следует имя функции sayHiа также parameter к функции, заключенной в круглые скобки.
  • Затем операторы, которые будут выполняться, будут заключены в фигурные скобки. { }
  • Запустите функцию, используя имя функции, за которым следуют круглые скобки. ().
  • () будет содержать argumentто есть фактические данные, которые вы хотите передать функции. argument введенные данные. Любые данные, которые мы вводим, будут храниться в parameter который служит заполнителем.
  • Наконец, в теле функции мы запускаем нашу задачу и выводим нужные данные пользователю.


Аргументы функции

Аргументы функции — это фактические значения, переданные (и полученные) функцией.

argument может быть любого типа данных (string, objects, arrays, numbers так далее.). Когда мы проходим необходимое argument к функции, она будет сохранена в parameter.

parameter служит заполнителем фактического передаваемого значения. Затем мы можем использовать parameter в теле функции для выполнения некоторых задач.

JavaScript позволяет нам передавать функцию в качестве аргумента другой функции и использовать эту функцию в теле внешней функции. Такой подход называется callback функция.

Ниже мы погружаемся, чтобы понять callback функция


Что такое функция обратного вызова?

Функция обратного вызова — это функция, которая передается как argument в другую функцию, которая затем вызывается внутри внешней функции для завершения какой-либо подпрограммы или действия.

Давайте посмотрим код ниже:

function firstFunc(anotherFunc){
//execute the other function
  anotherFunc()
}
// Define our callback function
function secondFunc(){
  console.log("I am another function called inside the outer function" )
}

//execute the firstFunc and pass the second function as the argument
firstFunc(secondFunc)
Войти в полноэкранный режим

Выйти из полноэкранного режима

Мы также можем использовать стрелочная функция а вторую функцию объявить непосредственно в основной функции.

См. код ниже:

firstFunc(()=>{  console.log("I am another function called inside the outer function" )
})
Войти в полноэкранный режим

Выйти из полноэкранного режима

Выход:

"I am another function called inside the outer function"
Войти в полноэкранный режим

Выйти из полноэкранного режима

  • В приведенном выше коде мы объявили две функции firstFunc а также secondFunc
  • Мы запускаем firstFunc функционировать и передавать secondFunc функционировать как аргумент.

Обратите внимание, что фактические данные, которые мы передаем в функцию, другая функция объявлен как secondFunc
Теперь в теле firstFunc мы можем бежать, т. secondFunc мы заявили.

  • Потому что мы проходим secondFunc в качестве аргумента для firstFunc, secondFunc становится нашим функция обратного вызова

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


Передача функции в другую функцию в качестве аргумента !

Функции рассматриваются как objects в JavaScript. Нравиться objects, функции имеют свойства и методы. Мы можем присвоить объект переменной, а также передавать объекты в качестве аргументов функции.

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


Пример функции обратного вызова.

Предположим, мы хотим выполнить определенные операции, например, сложить и умножить два числа. Мы можем просто объявить функции для этих задач, как показано ниже:


//addNum function
function addNum(x,y){
  return x +y
}

//multiplyNum function
function multNum(x,y){
  return x * y;
}

// run the addNum and multNum function
console.log(addNum(3,4))
console.log(multNum(3,4));
Войти в полноэкранный режим

Выйти из полноэкранного режима

Результатом этих операций будет

7
12
Войти в полноэкранный режим

Выйти из полноэкранного режима

Теперь, предположим, мы хотим расширить этот код, чтобы выводить определенный оператор перед выполнением операций, как мы к этому подойдем?

Мы можем объявить более высокого порядка функция (функция, которая принимает другую функцию в качестве параметра и возвращает эту функцию). В тело функции высшего порядка мы включаем** оператор для вывода** и требуемую функцию для запуска.

Давайте посмотрим, как этого добиться:

  • Определите функцию более высокого порядка, которая будет включать оператор, который будет выводиться
  • Определите задачи (математические операции), которые должны выполняться в соответствующих функциях.
  • Запустите функцию высшего порядка и передайте фактическая функция выполняться как argument.
  • В теле функции высшего порядка запустите фактическая функция для выполнения задачи

Код ниже будет таким:

//higher order function
function operateNum(callback, x, y){
    console.log(`Let's learn some operations using ${x} and ${y}`)
  // execute the callback function
   console.log(callback(x,y))
}

//addNum function
function addNum(x,y){
  return (`Adding ${x} and ${y} gives us: ${x + y}`)
}

//multiplyNum function
function multNum(x,y){
return (`Multiplying ${x} and ${y} gives us: ${x * y}`)
}


/* call the higher-order function and a pass it the addNum or multNum function 
   pass the actual numbers to perform the operation on.
*/
operateNum(addNum,3,4)
operateNum(multNum,3,4)

Войти в полноэкранный режим

Выйти из полноэкранного режима

  • В приведенном выше коде мы определяем operateNum как функция высшего порядка
  • Мы объявили две другие функции, addNum а также multiplyNum который принимает два числа и выполняет над ними сложение и умножение соответственно.
  • Мы запускаем operateNum функцию, а затем передать либо addNum или же multNum функционировать как argument к этому.
  • Мы также проходим operateNum два числа (3 и 4) в качестве аргументов.
  • При таком подходе мы теперь запустим addNum или же multNum функционировать только в operateNum функция.
  • addNum или же multNum функция может принимать два числа, переданные в operateNum

Потому что мы проходим addNum или же multNum как функции к operateNum, addNum а также multNum называются callback функции.

Мы будем только «вызов» эти функции позже внутри operateNum функция.

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


Зачем нам функция обратного вызова?

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

Однако бывают случаи, когда вы хотите, чтобы функция выполнялась после того, как что-то еще случилось.

  • Например, когда мы запрашиваем данные с сервера, требуется некоторое время, чтобы ответ дошел до нас.
  • В таких ситуациях нам придется ждать ответа прежде чем мы сможем перейти к следующей строке кода для выполнения.
  • Поскольку ожидание ответа может занять некоторое время, все наше приложение будет останавливаться пока данные извлекаются с сервера.
  • Этого сценария можно избежать, если мы используем callback функции.
  • Функция обратного вызова гарантирует, что функция будет запущена позже, сразу после завершения определенной задачи.

Существует два типа функций обратного вызова: **синхронные **и **асинхронные **функции обратного вызова.


Функция синхронного обратного вызова.

Синхронный обратный вызов выполняется ** во время ** выполнения функции более высокого порядка, которая использует обратный вызов.

Давайте разберемся в вышеизложенном на примере ниже:

function greetUser(name){
  console.log(`Hello ${name} welcome!!`)
}

function getUserInput(callback){
const userInput = prompt("Please enter your name");

  callback(userInput)

}

//execute the higher order function
getUserInput(greetUser)

console.log('waiting to run')
Войти в полноэкранный режим

Выйти из полноэкранного режима

В приведенном выше коде:

  • Мы проходим greetUser выступать в качестве аргумента getUserInput функция. greetUser наша функция callback функция. Он будет выполнен позже, когда getUserInput функция выполняется.
  • Мы проходим greetUser выступать в качестве аргумента getUserInput функционировать, потому что, greetUser зависит от значения из getUserInput. Следовательно, мы не хотим выполнять greetUser функционировать немедленно.
  • КогдаgetUserInput() выполняется, он предлагает ввести ввод.
  • greetUser функция опирается на введенное значение, как только это значение передается ей, greetUser функция также будет выполнена.

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

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


Примеры синхронных функций обратного вызова

Большинство встроенных методов JavaScript, особенно Array методы используют синхронные обратные вызовы. Любая функция, переданная нужному методу, будет выполнена сразу после запуска встроенного метода.

Примеры встроенных методов JavaScript:

  • array.map(callback)
  • array.forEach(callback)
  • array.reduce(callback) так далее

Взгляните еще раз на синхронную функцию обратного вызова, используя класс array.filter() метод

let numbers = [1, 2, 4, 7, 3, 5, 6];

const isOdd = (num)=>{
  return num % 2
}

const oddNumbers = numbers.filter(isOdd);

console.log(oddNumbers)
Войти в полноэкранный режим

Выйти из полноэкранного режима

Вывод кода будет

[1, 7, 3, 5]
Войти в полноэкранный режим

Выйти из полноэкранного режима

  • isOdd функция передается в качестве аргумента встроенной array.filter() метод.
  • Когда array.filter() метод выполняется, затем мы запускаем isOdd() функция.
  • Поскольку он синхронный, console.log(oddNumbers) блокируется в ожидании numbers.filter(isOdd) бежать.


Асинхронная функция обратного вызова

Выполняется асинхронный обратный вызов *после * выполнение функции высшего порядка.

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

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

Взгляните на код ниже:

console.log("start set timeout")

setTimeout(function callLater(){
  console.log("I will run later")
}, 3000)

console.log('end set timeout ')
Войти в полноэкранный режим

Выйти из полноэкранного режима

В приведенном выше коде callLater() является асинхронной функцией обратного вызова, потому что функция более высокого порядкаsetTimeout(callLater, 3000) начинает и завершает его выполнение. Однако, callLater() функция выполняется через 3 секунды.

Поскольку синхронные функции обратного вызова неблокирующийкод ниже setTimeout() функция, которая console.log('end set timeout') будет по-прежнему работать, пока выполняется функция обратного вызова.

Для проверки проверьте вывод кода ниже:

"start set timeout"
"end set timeout "
"I will run later"
Войти в полноэкранный режим

Выйти из полноэкранного режима


Пример 2: Выполнение функции обратного вызова для события

JavaScript — это язык программирования, управляемый событиями, поэтому мы можем выполнятьcallback работает, когда происходит событие, например, когда пользователь нажимает кнопку.

Давайте еще раз взглянем на асинхронную функцию обратного вызова.
В приведенном ниже коде мы запускаем handleClick() функция обратного вызова только тогда, когда button элемент был нажат.

//index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <button id="btn">Click me</button>
</body>
</html>

//index.js
const myBtn = document.getElementById("btn")

myBtn.addEventListener('click', function handleClick(){
  console.log('btn clicked')
})

console.log('non blocking so i will run')

Войти в полноэкранный режим

Выйти из полноэкранного режима

В коде выше

  • Мы выбрали button элемент с идентификатором btn из html и назначьте его myBtn переменная
  • Мы прикрепили addEventListener() функция для myBtn элемент
  • addEventListener() — это функция более высокого порядка, которая отслеживает событие «щелчок».
  • Мы проходим handleClick() функционировать как функция обратного вызова для функции более высокого порядка.

Когда код выполняется, addEventListener() функция будет сначала выполняться, а затем прослушивать click на button элемент.
В конце концов, при нажатии на кнопку handleClick() функция обратного вызова будет выполнена после выполнения функции более высокого порядка.

Поскольку асинхронные функции обратного вызова не блокируются, код ниже addEventLister() метод будет работать, пока handleClick()функция ожидает выполнения.

Вывод кода выше:

"non blocking so i will run"
"btn clicked"
Войти в полноэкранный режим

Выйти из полноэкранного режима

Асинхронность означает, что если JavaScript должен дождаться завершения операции, он выполнит остальную часть кода во время ожидания.


Резюме

Подведем итог тому, что мы узнали:

  • Функция высокого порядка — это функция, которая принимает другую функцию в качестве аргумента.
  • Функция обратного вызова — это функция, которая передается в другую функцию в качестве аргумента для последующего выполнения.
  • Функция обратного вызова гарантирует, что функция не запускается, когда выполняется задача (например, получение данных из API), но будет запускать только сразу после завершения задачи
  • Существует два типа функций обратного вызова: синхронные и асинхронные функции обратного вызова.

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