Почему следующий код JS не заканчивается в браузере? - PullRequest
0 голосов
/ 30 августа 2018
function foobar() {
  console.log('baz');    
  setTimeout(() => foobar(), 1000);
}

foobar();
throw new Error('terminate');

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

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Будьте интерпретатором JavaScript.

Давайте посмотрим список задач, которые должен выполнить интерпретатор JavaScript:


TaskList

[Выполнить основной код]


Теперь интерпретатор выполняет задачу построчно.

Выполнение foobar(); интерпретатор JavaScript собирается добавить новую задачу в свой список задач, который содержит функцию setTimeout() для выполнения.


TaskList

[Выполнить основной код (выполняется)] [Выполнить функцию setTimeout]


Затем, когда он достигает броска, он выдает ошибку и завершает фактическое выполнение задачи.

Он берет следующую задачу и выполняет ее:


TaskList

[Выполнить функцию setTimeout (выполняется)]


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

И снова, и снова, и снова, и снова ...


    function foobar() {
      console.log('baz');    
      setTimeout(() => foobar(), 1000);
    }
    
    foobar();
    throw new Error('terminate');
0 голосов
/ 30 августа 2018

Этот пример еще лучше иллюстрируется:

let attempts = 10;
function foobar() {
  if (!attempts--) return; // make it stop!
  console.log('baz');
  setTimeout(foobar, 1000);  
  throw new Error('terminate');
}
foobar();

См., Выдача ошибки прекращает выполнение текущей задачи, но не завершает браузер цикл обработки событий . И в цикле событий уже есть другая задача, находящаяся в своей очереди - запланированная setTimeout до того, как была выдана ошибка. Сполосните и повторите.


Однако на земле Node.js все по-другому: самое первое необработанное исключение в основном останавливает выполнение всего процесса . Это философия Узла - провал рано - и, хотя опрошено , он существует таким, какой он есть.

Тем не менее, с небольшими изменениями вы увидите похожую картинку. Просто добавьте эти строки в скрипт:

process.on('uncaughtException', function (err) {
  console.error('CAUGHT', err);
});

... и вы увидите довольно похожий рисунок.

...