#javascript
#javascript
Вопрос:
setTimeout(function timeout() {
console.log("Click the button!");
}, 100);
console.log("1");
console.log("2");
console.log("3");
console.log("4");
console.log("5");
console.log("6");
console.log("7");
У меня есть вопрос о цикле событий и о том, как задачи, поставленные в очередь, помещаются в стек в JS. Учитывая приведенный выше код, у меня есть короткий setTimeout с инструкцией log внутри.
После этого, допустим, у меня есть console.log()
от 1 до 1 000 000 (только 7 в моем коде по понятным причинам).
Мое понимание того, что происходит, таково:
- setTimeout добавляется в стек вызовов
- он извлекается из стека вызовов и обрабатывается веб-API, который использует тайм-аут
- по истечении тайм-аута в 1 мс тайм-аут передается в очередь задач для запуска после очистки стека.
Затем цикл событий помещает то, что находится в очереди задач, в стек, как только стек очищается и отображается журнал внутри таймаута. Однако что означает, что стек должен быть чистым? Начиная с каждой отдельной консоли.журнал должен быть добавлен в стек и немедленно удален, удастся ли поставленной в очередь задаче проникнуть в стек и запуститься до того, как все эти числа будут зарегистрированы до 1 000 000?
setTimeout(function timeout() {
console.log("Click the button!");
}, 100);
console.log("1");
console.log("2");
console.log("3");
console.log("4");
console.log("5");
console.log("6");
console.log("7");
// pretend console.log all the way up to 1,000,000
Комментарии:
1. да, ваше понимание верно. Сначала в стек вызовов был добавлен setTimeout, а затем следующие счетчики журналов от 1 до 1 000 000. Через 100 мс журнал для «Нажатия кнопки» был добавлен последним в очередь. Причина, по которой задача в очереди не была вставлена между отдельными консолями. журнал основан на приоритете, задача, поставленная в очередь, возвращается в основной поток только после того, как он больше не занят.
2. Спасибо. Когда вы говорите «основной поток больше не занят», что это означает? Что, если после всех этих журналов консоли был отдельный вызов функции из этого метода … этот тайм-аут ВСЕ ЕЩЕ ожидает в очереди?
3. Эта
setTimeout
задача будет вызвана, когда стек будет очищен. Стек будет очищен, когда весь синхронный код завершится. Это включает в себя всеconsole.log
s, другие вызовы func и, в основном, все, что само по себе не ставит в очередь другую задачу. Таким образом, выsetTimeout
будете приятно ждать всех вашихconsole.log
действий и тому подобных вещей, даже если на их выполнение уйдет 10 секунд4. (к предыдущему комментарию) «основной поток не занят» в данном случае означает то же самое, что и «стек пуст»…
5. @LegoGeo К сожалению, это тоже очень сложный вопрос, поскольку основной поток каким-то образом ненадежен и не всегда работает одинаково для каждого устройства, поэтому очень сложно оценить, когда вы узнаете, что основной поток больше не занят на микроскопическом уровне. Но что вы можете сделать, чтобы понять, что делает основной поток, — это оценить страницу с помощью DevTools, перейти на вкладку «Производительность» и создать «Профиль» на странице с помощью скрипта, который покажет вам временную шкалу вместе со стеками вызовов.
Ответ №1:
Да, функция тайм-аута будет выполняться после каждого другого console.log. Просто протестируйте написанный вами код.
setTimeout(function timeout() {
console.log("DONE");
}, 1);
for(let i=0;i<100000;i )
console.log(i);