Подвисает браузер на "тяжелой" задаче.
Друзья, подскажите, пожалуйста.
Какой правильно подход использовать для разбиения "тяжелой" процедуры на подзадачи, как везде советуют . В таком коде браузер зависает с сообщением "окно не отвечает ...Подождать?" ...Promise.then((...) => { // всякие преобразования... долго выполняемый код }) Идеально на экран выдавать прогрессбар...но, как я понимаю, рендер будет ждать окончания "тяжелого" кода и потом что-то нарисует. Спасибо. |
Цитата:
Потом с некой периодичностью опрашиваю сервер с этой "ссылкой/ключем" и получаю ответ типа "готово или нет" и "на каком этапе"... Если готово - запрашиваю данные. Если не готово - как-то отображаю "прогресс" на клиенте... |
Тяжелый код сейчас можно пихать в webworker.
Вот тут недавно делал простой пример(содержимое не суть). Либо разбивать ваши вычисления на куски, которые уже в свою очередь вызывать через Promise.then. Просто засунуть код в Promise.then никак вам не поможет, это не магия. |
Цитата:
|
Или requestIdleCallback, если не думать про Safari
|
Цитата:
|
Цитата:
|
сonst aLittle = () => new Promise(setTimeout);
for(let i = 0; i < length; i++) {
// code
if(i%1000 === 0) await aLittle();
}
=) |
Цитата:
// количество итераций, которое надо сделать
const N = 100500 ;
// гарантировано без тормозов можно сделать итераций
const NS = 100;
let start = 0;
function workns () {
const ne = Math.min(N, start+NS)
let i;
for (i = start; i< ne; i++) {
/* тут делаем итерацию */
}
start = i;
}
function idleWork (time) {
while (time.timeRemaining() > 0 && start < N) {
workns()
}
if (start < N) requestIdleCallback(idleWork);
}
requestIdleCallback(idleWork);
Немного похоже на requestAnimationFrame, но есть возможность проверить( .timeRemaining() ) - сколько времени еще примерно есть |
Цитата:
Запускаешь в setTimeout()... Процесс пишет что-то о себе в "общедоступное место"... Остается только с неким таймаутом мониторить "то место" и по готовности получить данные для использования. |
Цитата:
|
Цитата:
|
Цитата:
Цитата:
|
voraa, рендеринг "по готовым данным" можно запускать и из процесса "обработчика".
Т.е. собственно мониторинг может только показывать "состояние дел". А сами изменения на клиенте может запускать процесс-обработчик некими "порциями". Подготовил N-ное количество - запускай setTimeout(), который все N штук и отрисует... Тут главное чтобы сам "источник данных" был доступен всем процессам-участникам. |
Цитата:
Цитата:
Используя setTimeout, мы тупо пихаем очередное задание в очередь, не зная сильно ли она заполнена. Есть ли у браузера время обработать это задание не тормозя прорисовку. А requestIdleCallback выполняет задание именно тогда, когда браузер не занят обработкой событий, пересчетом стилей и прорисовкой. К тому же внутри задания можно узнать, осталось ли еще время, что бы посчитать очередную порцию. |
Цитата:
Потому и указывал много чего в кавычках... |
Цитата:
А коней на переправе не меняют. Т.е. работает такой подход уже давно... А нужен он далеко не всегда. |
Цитата:
Я лишь описал как выходил их таких положений ранее сам. |
Цитата:
https://developer.mozilla.org/ru/doc...stIdleCallback И сразу там увидел большое сообщение Цитата:
|
Цитата:
Это не повод ездить на старых клячах. Цитата:
Для Safari есть типа полифил (реализованный как раз через setTimeout). Ну хоть в нормальных браузерах будет нормально работать. |
Цитата:
Их тебе, по прошествии времени, скажут молодые программисты. :D |
Цитата:
Я не знаю ни Vue, ни React. И ваще, даже по новым законам, мне в следующем году на пенсию. |
Цитата:
|
Цитата:
Ребят, спасибо. По моему в моей ситуации эту штуку проще всего реализовать...Классная вещь.. Спасибо. |
| Часовой пояс GMT +3, время: 18:45. |