#javascript
#javascript
Вопрос:
У меня есть программа, которая записывает множество результатов if. Например, это:
const a = prompt();
for(let i = 1; i < a; i ) {
console.log(i);
}
(не фактический код)
Итак, когда вы вводите большое число, появляется тонна ответов, ожидающих ввода в консоль. Итак, когда он достигает некоторой точки, встроенный компилятор браузера (Opera GX) просто перестает работать. Надеюсь, мне нужен какой-то способ записать эти числа сразу после вычисления, не теряя времени. Как я могу это сделать?
(просто чтобы вы знали, мой фактический код помещает результаты в элемент «div»)
Комментарии:
1. «встроенный компилятор просто перестает работать» Вы должны уточнить это.
2. В чем разница между мгновенно и немедленно? В заголовке: «Как заставить JavaScript записывать результат с течением времени (не мгновенно)?» и в описании: «Мне нужен какой-то способ немедленно записать эти числа»
3. Мгновенно означает «сохранение этих значений для печати после завершения программы». Немедленно означает «Я вычислил это число. Я должен поместить его в консоль и начать вычислять другой «. Точно так же, как в Python (но, надеюсь, намного быстрее)
4. Вы могли бы попробовать рекурсивный
setTimeout
. Это разобьет один долго работающий код на множество небольших фрагментов, управляемых циклом событий. Что-то вродеlet i = 0; setTimeout(function f() { i; console.log(i); if (i < a) setTimeout(f, 0); }, 0);
5. Вы обращались к сервисным работникам? developers.google.com/web/fundamentals/primers/service-workers
Ответ №1:
JavaScript является однопоточным. Это означает, что во время выполнения вашего цикла события не могут быть обработаны, и страница не отвечает. Вы могли бы использовать «рекурсивный» setTimeout
. Это разобьет один долго выполняющийся код на множество небольших фрагментов, управляемых циклом событий.
const a = prompt();
const container = document.getElementById('container');
const f = (() => {
let i = 0;
return () => {
for (let j = 0; j < 1e9; j) {} // simulates long calculation
i;
console.log(i);
container.innerText = ' ' i;
if (i < a) setTimeout(f, 0);
};
})();
setTimeout(f, 0);
<div id="container"></div>
Это не настоящий рекурсивный вызов, и он не создаст большой стек вызовов. setTimeout(f, 0)
помещает событие в цикл событий, который почти сразу же удаляется и обрабатывается.
Я использовал закрытие только для того, чтобы избежать глобального счетчика i
. Более простая, но менее чистая версия
const a = prompt();
const container = document.getElementById('container');
let i = 0;
function f() {
for (let j = 0; j < 1e9; j) {} // simulates long calculation
i;
console.log(i);
container.innerText = ' ' i;
if (i < a) setTimeout(f, 0);
};
setTimeout(f, 0);
<div id="container"></div>
Помните, что страница по-прежнему не реагирует во время циклов (длительное вычисление), но теперь у вас есть много более коротких циклов вместо одного длительного цикла, а события обрабатываются между двумя циклами.