Метод setTimeout (), как следует из названия, вызывает функцию по истечении указанного времени.

Или нет?

Но прежде всего синтаксис. Ниже приведен синтаксис setTimeout (), который оценивает функцию и выводит сообщение «Hello!» Через 3 секунды (3000 миллисекунд).

Теперь давайте запустим простой код и посмотрим, как должна работать setTimeout ().

Ввод:

Вывод. Как видно, приведенный выше код выполняет выход из системы: «Эй!», затем идет «Прощай», и по прошествии 3 секунд он выходит из системы: «Давай поиграем с JavaScript».

Легко, правда? Верно. А теперь давайте возьмем другой пример.

Ввод: на этот раз вместо 3 секунд мы установим задержку в 0 секунд.

Вывод. Технически он должен печатать сообщения в следующем порядке: «Эй!», «Давай поиграем с JavaScript» и, наконец, «Прощай». Но это не так. Вместо этого он выводит их из системы в таком порядке, как указано ниже.

Это потому, что setTimeout () неблокирующий.

Прежде чем объяснять, что это такое, давайте рассмотрим еще один пример. В приведенном ниже примере я использовал цикл while, чтобы задержать регистрацию Adios на 5 секунд. В то время как setTimeout () имеет таймер на 3 секунды.

Так должен ли браузер выходить из системы «Давай поиграем с JavaScript» перед «Адиос»? Давай узнаем.

Ввод:

Ответ на вышеупомянутый вопрос: в параллельной идеальной вселенной, возможно, следует выйти из системы «Adios» перед «Давай поиграем с JavaScript», но здесь этого не происходит. Вместо этого

Вывод:

Итак, что произошло? Почему он вышел из системы "Adios", играя с JavaScript? Почему бы setTimeout () не вести честную игру?

Возвращаясь к setTimeout (). Странно, не правда ли? Но только до тех пор, пока мы не узнаем, что скрывается за всем этим.

Итак, как работает браузер?

Что такое модель параллелизма?

Почему setTimeout () ведет себя как засранец?

Почему я всегда сбиваюсь с пути и все такое прочее? (Может, не этот)

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

Читайте дальше, через минуту все это обретет смысл.

Модель параллелизма. Время от времени мы слышали, что JavaScript - это однопоточный язык. Это означает, что у него один стек вызовов, и он будет выполнять только одну вещь за раз до своего завершения.

Итак, в JavaScript есть модель параллелизма, основанная на цикле событий, который синхронно ожидает сообщения, если оно еще не присутствует или не ожидает выполнения.

Стек вызовов. Стек вызовов обрабатывает контекст выполнения. Как следует из названия, он работает по принципу LIFO (last in first out). Любой оператор (блокирующий и неблокирующий) или функция, которая должна быть выполнена, помещается в верхнюю часть стека вызовов, и после ее завершения она извлекается из него.

Очередь обратного вызова: я объясню очередь обратного вызова, исходя из того, что может быть предположением.

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

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

Вот наглядное изображение приведенного выше объяснения.

А теперь давайте еще раз проанализируем третий пример с помощью этой диаграммы.

После выполнения оператор удаляется из стека вызовов.

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

Скажем, есть миллион строк кода после setTimeout () (посмотрите еще раз на этот пример, где я специально использовал цикл while, чтобы задержать процесс на 5 секунд).

В аргументе функции setTimeout () обязательно указано 3000 миллисекунд, но теперь мы знаем, что она не будет выполнена через 3 секунды. Сначала будут выполнены все операторы блокировки, а затем они будут выполнены чуть позже, через 5000 миллисекунд. Вот почему команда «Давай поиграем с JavaScript» отключается после «Адиос».

Другими словами, время, указанное в аргументе setTimeout (), не является временем выполнения функции, а фактически временем, по истечении которого она перемещается в очередь обратного вызова.

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

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

Если вы хотите вникнуть в них, попробуйте сами и прочтите об этом подробнее. Вот ссылки на несколько ресурсов, которые мне помогли:

MDN Web Docs, Знакомство с setTimeout (), W3Schools, Акшай Сайни

Я читал с разных ресурсов и добавил несколько выше, так как невозможно упомянуть все ссылки. Однако все, что помню, я добавлю еще в будущем.

Если вам это понравилось, поделитесь им.

И вы можете связаться со мной в Twitter здесь и / или LinkedIn здесь.

Спасибо за прочтение!