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

Или го прави?

Но преди всичко друго, синтаксис. По-долу е синтаксисът на setTimeout(), който оценява функцията и излиза „Здравей!“ след 3 секунди (3000 милисекунди).

Сега нека стартираме прост код и да видим как трябвада работи setTimeout().

Вход:

Изход: Както е видно, горният код излиза от системата „Хей!“, след това идва „Адиос“ и след като изминат 3 секунди, излиза от системата „Да си поиграем с JavaScript“

Лесно, нали? Правилно. Сега нека вземем друг пример.

Въвеждане:Този път вместо 3 секунди, ще го зададем на забавяне от 0 секунди.

Резултат:Технически трябва да отпечата нещата в реда „Хей!“, „Да си поиграем с JavaScript“ и накрая „Адиос“. Но това не е така. Вместо това ги извежда в този ред, както е дадено по-долу

Това е така, защото setTimeout() е неблокиращ.

Преди да обясним какво е това, нека да разгледаме друг пример. В примера по-долу използвах цикъл while, за да забавя записването на „Adios“ с 5 секунди. Докато setTimeout() има таймер за 3 секунди.

Значи трябва ли браузърът да излезе от „Да играем с JavaScript.“ преди „Адиос“? Нека разберем.

Вход:

Отговорът на въпроса по-горе: В една паралелна идеална вселена може би трябва да се излезе от „Adios“ преди „Lets play with JavaScript“, но тук това не се случва. Вместо това това прави

Изход:

И така, какво се случи? Защо излезе „Адиос“ при игра с JavaScript? Защо setTimeout() не играе честна игра?

Връщам се към setTimeout(). Странно, нали? Но само докато не разберем какво влиза в задната част на всичко това.

И така, как работи браузърът?

Какъв е моделът на едновременност?

Защо setTimeout() се държи като нахалник?

Защо винаги се отклонявам от коловоза и целия този джаз?(Може би не този)

Както беше споменато преди, setTimeout() е неблокиращ. Той ще се изпълни само след като всички изрази извън него са били изпълнени, за разлика от блокиращия код, който блокира по-нататъшното изпълнение, докато тази операция не приключи.

Прочетете, всичко това ще има смисъл след минута.

Модел на паралелност: Чували сме веднъж или друг път, че JavaScript е език с една нишка. Това означава, че има един стек за повиквания и ще изпълнява само едно нещо наведнъж до завършването му.

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

Стек за повиквания: Стекът за повиквания управлява контекста на изпълнение. Както подсказва името, той работи на принципа LIFO (последен влязъл, първи излязъл). Всеки оператор (блокиращ и неблокиращ) или функция, която трябва да бъде изпълнена, се избутва в горната част на стека за извикване и след като завърши, се изважда от него.

Опашка за обратно повикване: Ще обясня опашката за обратно повикване чрез това, което може да бъде предположението.

Предположение (което може да има): setTimeout() изчаква определеното време и след това извиква функцията за изпълнение.

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

Ето картинно представяне на горното обяснение

Сега, нека анализираме третия пример отново с помощта на тази диаграма

След като операторът бъде изпълнен, той се премахва от стека за извикване.

И ето как, въпреки че setTimeout() е указано да се изпълнява след 0 милисекунди, функцията се изпълнява само след като всички блокиращи оператори вече са изпълнени.

Да кажем, че има милиони редове код след setTimeout() (Погледнете отново този пример, където използвах цикъл while, за да забавя процеса с 5 секунди нарочно).

Функцията setTimeout() със сигурност има 3000 милисекунди, посочени в аргумента, но сега знаем, че няма да се изпълни след 3 секунди. Първо всички блокиращи оператори ще бъдат завършени и след това ще бъдат изпълнени малко по-късно след 5000 милисекунди. Ето защо „Да си поиграем с JavaScript.“ излиза от системата след „Адиос“.

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

Вижте, казах ви, че всичко ще има смисъл след минута (Добре, може да е повече от минута). Надявам се, че това ви помогна да разберете тази концепция малко по-добре.

Човек винаги може да научи повече и това са моите интерпретации на тези понятия. Ако установите, че нещо не е обяснено по правилния начин, кажете ми, това ще ми помогне да подобря разбирането си. Ще приема положително всички конструктивни отзиви (било то за концепциите или за статията).

Ако искате да се задълбочите в тях, опитайте сами и прочетете повече за това. Ето връзките към няколко ресурса, които ми помогнаха:

MDN Web Docs, Разбиране на setTimeout(), W3Schools, Akshay Saini

Четох от различни ресурси и добавих няколко по-горе, тъй като не е възможно да спомена всички връзки. Въпреки това ще добавя всичко, което си спомням дори в бъдещето.

Ако това ви е харесало, споделете го.

И можете да се свържете с мен в Twitter тук и/или LinkedIn тук.

Благодаря за четенето!