Почему цикл событий Javascript требует завершения глобального контекста выполнения перед выполнением функций в очереди обратного вызова - PullRequest
0 голосов
/ 13 июня 2019

Насколько я понимаю, перед выполнением элемента в очереди обратного вызова необходимо выполнить два условия:

  1. Все кадры в стеке вызовов должны быть извлечены
  2. Весь код в глобальном контексте выполнения должен быть завершен.

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

1 Ответ

1 голос
/ 13 июня 2019

Я думаю, что главное недоразумение заключается в «callstack» здесь: Давайте возьмем это:

  (function A() {
    (function B() {
      setTimeout(function C() {
         (function D() { })();
      });
    })();
 })();

Прежде всего, код инициализируется, вызывается A и вызывается B, стек вызовов выглядит следующим образом:

  [init] -> A -> B

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

Теперь Через некоторое время , таймер вызовет обратный вызов:

 [timer] ->

И тогда это вызовет C:

 [timer] -> C

внутри C, D будет называться:

 [timer] -> C -> D 

поскольку код не остался, стек вызовов снова раскручивается. Как видите, A и B больше не находятся в стеке вызовов, они оставили его давным-давно . Поэтому

setTimeout был вызван в локальном контексте выполнения. Разве нам не нужно только ждать, пока все кадры выше локального контекста выполнения, где был вызван setTimeout, будут удалены?

Не имеет особого смысла, потому что "контекст был setTimeout" был выполнен в является самый верхний контекст выполнения.

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

...