Концепция синхронного и асинхронного программирования в JavaScript - Часть 1
При выполнении
JS
одна из концепций, которая сбивает с толку многих разработчиков от новичков до разработчиков среднего уровня, - этоAsynchronous (‘Async’) programming
. Поскольку это одна из наиболее распространенных концепций вJavaScript
, вам необходимо хорошо ее понять, прежде чем углубляться вJavaScript
.
Итак, основываясь на своих исследованиях и выводах, я решил написать статью о Concept of Synchronous & Asynchronous Programming in JavaScript
, которая разделена на 3 части, охватывающие следующие концепции соответственно:
В этой части мы обсудим первый пункт в списке - Basics of Synchronous and Asynchronous Programming in JavaScript
вместе с некоторыми интересными примерами. Я прошу вас, ребята, попрактиковаться в примерах самостоятельно для лучшего понимания.
В общем, синхронный код можно определить как - «набор последовательных операторов». т.е. каждый оператор в коде выполняется один за другим сверху вниз, пока последний оператор не завершит выполнение. Таким образом, каждая инструкция должна ждать завершения выполнения предыдущей.
Давайте попрактикуемся на примере, чтобы визуализировать наше утверждение:
let a = 30 let b = 50 console.log(a) console.log(b)
Коды выполняются последовательно, и мы получаем следующий результат:
30 50
Давайте перейдем к другому примеру с использованием синхронных функций;
let a = function(){return 20} let b = function(){return 30} console.log(a()) console.log(b())
Если мы запустим этот блок кода, мы получим следующий результат:
20 30
То, что я хочу передать, не имеет значения, каким бы сложным он ни был, каждый оператор будет выполняться сверху вниз, то есть sequentially
. Функция будет выполнена, затем будет присвоено возвращаемое значение и, наконец, будет выполнена следующая строка. Первый метод может иметь внутри более 1000 строк, но все равно потребуется все время для выполнения операторов внутри него, и тогда будет выполняться только присваивание. И все это до того, как будет выполнена следующая строка. Такова концепция Synchronous Programming
, и это то, что JavaScript
делает большую часть времени.
Но рассмотрим ситуацию, когда нам нужно получить некоторые данные с сервера, что может занять некоторое время в зависимости от подключения к Интернету, размера данных или любой другой зависимости. Мы не можем просто заморозить пользовательский интерфейс на время выполнения. Это не мгновенно. Вот тут-то и начинается асинхронное программирование.
Давайте рассмотрим пример использования setTimeout()
, который является очень простым примером Asynchronous Programming
:
let a = 4 let b = 3 setTimeout(function() { console.log("Async Task 1") }, 100) console.log(a) setTimeout(function() { console.log("Async Task 2") }, 90) console.log(b)
Результатом вышеуказанного блока кода будет:
4 3 Async Task 2 Async Task 1
Мы видим, что хотя setTimeout()
идет раньше, он печатается в последнюю очередь. Это потому, что для выполнения setTimeout()
требуется 100 мсек.
Как
Asynchronous
метод, он выполняется после выполнения всех синхронных задач, несмотря на положение блоков кода. Таким образом, концепция заключается в том, что если мы используемAsynchronous Programming
для выполнения не мгновенных задач, следующей задаче не придется ждать завершения предыдущей для выполнения.
В приведенном выше примере, даже если мы установим время задержки равным 0 ms
, мы заметим аналогичное поведение, поскольку Synchronous
задачи всегда выполняются перед Asynchronous
задачами независимо от позиции. После завершения Synchronous
задач, Asynchronous
задачи выполняются впоследствии в порядке, соответствующем их времени выполнения. Если вы заметили результат, вы можете увидеть, что Async Task 2
печатается перед Async Task 1
, поскольку время задержки второго setTimeout()
меньше, чем у первого.
Примечание. Я предлагаю всем выполнить приведенный выше пример, изменив время задержки, и внести некоторые другие изменения, чтобы лучше понять и получить четкую концепцию, если вы все еще не уверены.
Исходя из того, что мы обсуждали, последняя вещь, которая может сбивать с толку, - это использование переменных при использовании любых форм
Asynchronous
функции. В таких случаях обычно лучше передать переменные в этуAsynchronous
функцию, чем полагаться на них извнеAsynchronous
функции, поскольку они могут быть изменены остальной частью программы перед выполнением этой конкретной функции / блока.
Приведем последний пример, чтобы прояснить, что я пытаюсь передать.
let a = 1 let b = 2 setTimeout(function() { console.log("Async Task a = ", a) }, 10) a = 5 // change the value of a after setTimeout() console.log(a) console.log(b)
Если вы запустите этот блок кода, на выходе мы получим следующее:
5 2 Async Task a = 5
Как видите, даже если a
присвоено другое значение после setTimeout()
, результат setTimeout()
будет Async Task a = 5
. Это связано с тем, что, как мы обсуждали ранее, setTimeout()
являясь Asynchronous
функцией по умолчанию, она выполняется после того, как все остальные Synchronous
задачи выполняются последовательно, независимо от установленного времени. То есть, даже если мы установим время задержки на0ms
, мы будем наблюдать такое же поведение. Итак, переменная a уже установлена в 5
перед выполнением setTimeout()
, в результате чего будет получен вышеуказанный результат.
Наконец, мы можем заключить, что Asynchronous Programming
упрощает обработку более чем одной задачи за раз и позволяет выразить ожидание длительных действий без зависания программы во время этих действий.
На этом пока все. Надеюсь, вам стало легче понять основную концепцию. Мы высоко ценим любые предложения по этой статье, так как это моя первая статья.
Следующая часть этой статьи посвящена обратным вызовам и обещаниям, которые упростили асинхронное программирование. Щелкните здесь, чтобы перейти к следующей части этой статьи: Часть 2