Многие слышали, что Javascript работает в одном потоке, т.е. он выполняет только одну вещь за раз. Это означает, что выполнение кода Javascript блокируется до тех пор, пока не будет выполнена определенная строка кода для возврата значения. Синхронное выполнение кода Javascript не сможет эффективно использовать выделенные ему системные ресурсы, и все выполнение останавливается до тех пор, пока конкретная строка кода не вернет значение.

Чтобы преодолеть вышеуказанную проблему, Javascript вводит асинхронное выполнение функции с использованием очереди событий и веб-API в браузере. Только Javascript работает в одном потоке, а не в браузере.

Итак, как именно javascript собирается преодолеть свою неспособность работать с несколькими потоками, используя асинхронные функции и циклы событий??

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

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

Давайте пройдемся по этому коду построчно

  1. console.log перемещается в стек, выводит «Введите код» и удаляется из стека вызовов.
  2. Выделяет память для функции один (вызываемый объект)
  3. Выделяет память для третьей функции (вызываемый объект)
  4. Первая функция вызывается и помещается в стек вызовов.
  5. console.log помещается в стек, распечатывается и удаляется из стека вызовов.
  6. Выделяет память для функции два (вызываемый объект), и функция два вызывается и помещается в стек вызовов.
  7. первая функция удаляется из стека вызовов, а вызов возвращается в основную область.
  8. третья функция помещается в стек вызовов.
  9. console.log помещается в стек, печатает два и удаляется из стека вызовов.
  10. третья функция удаляется из стека вызовов.

Вышеприведенный код, похоже, работает нормально, верно? Но рассмотрим сценарий, в котором мы отправляем HTTP-запрос для получения данных с сервера. Что произойдет, если мы выполним этот код синхронно?

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

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

Так что же такое асинхронная функция? Как это будет полезно при написании неблокирующего кода?

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

Давайте поймем это с помощью следующего блока кода.

  1. Когда мы нажимаем кнопку 1, анонимная функция помещается в стек вызовов.
  2. Запрос на выборку вызывается, и запрос отправляется на сервер с использованием веб-API.
  3. Но здесь выполнение кода не блокируется до тех пор, пока не будет возвращен ответ. Вместо этого он напечатает «exiting click 1» до того, как придет ответ.
  4. Атлас. Когда ответ получен, функция обратного вызова помещается в очередь цикла событий, ожидая, пока стек вызовов не станет пустым.
  5. Поскольку в стеке вызовов нет функций, функция в цикле событий затем помещается в стек вызовов, а затем console.log печатает «внутри 1-го ответа».

Итак, как именно помогают асинхронные функции?

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

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

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

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