Весь синхронный код в скрипте будет выполнен до того, как обратные вызовы получат возможность запуска. Если у вас есть код, который блокирует (например, бесконечно yield
в цикле while
без остановки), обратный вызов никогда не будет иметь возможности для запуска.
По тем же причинам следующий код никогда не выйдет из цикла while
:
let flag = false;
setTimeout(() => flag = true);
while (!flag) {
// do something
}
Проверьте, не прошло ли 100 мсек внутри вместо цикла:
function* pseudoRandom(seed) {
let random = seed;
const start = Date.now();
while (Date.now() - start < 100) { // stop generating after 100ms
random = random * 16807 % 2147483647;
yield random;
}
}
let generator = pseudoRandom(1);
console.log([...generator].length);
Обратите внимание, что число элементов, генерируемых за 100 мс, может иметь очень большой диапазон, в зависимости от того, что еще процессор / браузер делает в это время.
Спасибо, Кайидо. Чтобы не блокировать видимый пользовательский интерфейс, вы можете рассмотреть вопрос о переносе блокирующей части скрипта на рабочего:
// https://stackoverflow.com/questions/10343913/how-to-create-a-web-worker-from-a-string
// I put in a Stack Snippet for live demonstration
// in a real project, put this in a separate file
const workerFn = () => {
function* pseudoRandom(seed) {
let random = seed;
const start = Date.now();
while (Date.now() - start < 100) { // stop generating after 100ms
random = random * 16807 % 2147483647;
yield random;
}
}
self.onmessage = ({ data }) => {
let generator = pseudoRandom(1);
const arr = [...generator];
self.postMessage(arr.length);
};
};
const workerFnStr = `(${workerFn})();`;
const blob = new Blob([workerFnStr], { type: 'text/javascript' });
const worker = new Worker(window.URL.createObjectURL(blob));
worker.onmessage = ({ data: length }) => console.log(length);
worker.postMessage(1234);