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

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

Допустим, мы хотим выполнить операцию умножения и деления числа. Как вы это сделаете?

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

В качестве примера предположим, что у вас есть два массива, и вам нужно умножить каждый элемент на 2 для первого массива и разделить каждый элемент на 2 для второго массива. Тогда как вы это сделаете?

В приведенном выше коде операция ( arr[index] ) берет каждый элемент массива и в зависимости от выполняемой операции вызывает умножение на 2 () или деление на 2 (). Здесь мы передаем функции ( muliplyBy2 или DivisionBy2 ) в качестве параметра функции arrayOperation(). Что делает умножение на 2() и деление на 2() в качестве функций обратного вызова. Функция arrayOperation() принимает в качестве аргумента другую функцию, поэтому она называется функцией более высокого порядка.

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

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

2. Синхронные функции обратного вызова

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

Во-первых, нам нужно понять, что такое стек вызовов , чтобы понять, как работает функция обратного вызова.
стек вызовов
 – это структура данных стека для поддержки текущей функции исполнение. Стек поддерживается движком javascript. Вот пример, когда нам нужно умножить каждый элемент массива на 2.

Чтобы объяснить работу стека вызовов, давайте сохраним длину массива равной 1. Когда программа запускается, в стеке вызовов происходят следующие вещи.

  1. Функция arrayOperation() выполняется и помещается в стек.
  2. ArrayOperation() вызывает функцию обратного вызоваmultiBy2(), и функция обратного вызоваmultiBy2() помещается в стек.
  3. ФункцияmultiBy2()выполняется и извлекается из стека, возвращая управление обратно в arrayOperation().
  4. ArrayOperation() завершает выполнение и выталкивается из стека, оставляя стек пустым.

Здесь функция более высокого порядка arrayOperation() не завершает свое выполнение до тех пор, пока не завершится выполнение функции обратного вызова multipleBy2(). Вот как синхронный обратный вызовфункция работает.

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

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

В приведенном выше примере setTimeout() — это асинхронная функция высшего порядка функция, а multiplyBy2() — функция обратного вызова. Если вы понаблюдаете за выводом, вы будете поражены, увидев, что функцияdivideBy2() была выполнена раньше, чемmultiBy2().

Но как это возможно? Это все из-за асинхронной природы javascript.

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

В javascript, выполняющем HTTP-запрос с использованием функций таймера (например, setTimeout()), сокеты обрабатываются асинхронно.

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

Когда программа запускается, в стеке вызовов происходят следующие вещи.

  1. Функция multipleBy2(), присутствующая внутри setTimeout(), помещается в очередь обратного вызова.
  2. Функция DivisionBy2() помещается в стек вызовов и выполняется.
  3. После завершения функции DivisionBy2() она извлекается из стека обратного вызова.
  4. Так как callStack пуст и нам нечего помещать в стек, функцияmultiBy2() в очереди обратного вызова берется и помещается в стек вызовов.
  5. ФункцияmultiBy2(), присутствующая в стеке вызовов, выполняется
  6. ФункцияmultiBy2() выскакивает из стека вызовов.

Как javascript узнает, что стек вызовов пуст?
движок javascript поддерживает цикл, который постоянно проверяет, пуст ли стек вызовов или нет. Если он пуст, то он извлекает функции из очереди обратного вызова и помещает их в стек вызовов. Этот цикл называется циклом событий.

Таким образом, правило состоит в том, чтобы добавить все асинхронные функции в очередь и добавить синхронные функции в стек вызовов. А когда стек вызовов пуст, цикл событий будет выбирать по одной функции за раз и помещать ее в стек вызовов.

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