Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Синхронизация и работа с асинхронными функциями по событиям.  (Прочитано 2411 раз)
0 Пользователей и 1 Гость смотрят эту тему.
BlueWhite
Интересующийся

il
Offline Offline
Пол: Мужской

« : 18-06-2019 08:58 » 

Друзья, нужна помощь в javascript
Есть событие при обработке которого находятся все элементы страницы которые удовлетворяют условию, определенный class-name.
Далее проверяется нужно ли применять некую обработку и если да, то запускается async функция обработчик, которая внутри использует await дабы сделать эффект плавным.
Все в асинхронной функции обрабатывается в цикле, который занимает менее 1 секунды.
Однако события могут происходить быстрее.

Если удалять обработчик события до того, пока не закончится асинхронная обработка всех объектов, то эффект будет не полным при быстрой смене условий. Т.е. например при прокрутке видимость объекта будет оставаться на уровне который был в момент запуска обработчика первый раз, а при быстрой прокрутке один, два вызова будут пропущены и в центре сайта будет не до конца проявленный объект.
Если же обработчик не удалять, а запускать вновь, то он запустит асинхронные функции еще раз, и два экземпляра обработчика одного и того же объекта вызовут моргание в связи с разными конечными условиями, например про прокрутке вверх и вниз, две асинхронных функции будут одновременно увеличивать и уменьшать степень видимости объекта. Что жуть для пользователя.

Решения которые я не хочу применять - использование transition свойства для классов CSS. Это решение для меня не красиво, так как придется перепрописывать динамически статические классы, а я такие хаки не люблю. Да и не знаю, будет ли работать быстро многократное переназначение свойство opacity для уже стартовавшего transition эффекта в браузере.
Второе решение это передавать в асинхронные функции глобальные переменные, которые использовать как причину для прекращения работы предыдущей функции в случае старта ее копии, такая типовая state-машина. Это хорошо бы работало в случае наличия возможности линковать объекты на странице сразу с дополнительными данными, но этого нет, а так как заранее неизвестно число объектов на странице - это не лучшее решение использовать статические размеры массивов данных дабы синхронизировать асинхронность.

Лучшим решением был бы поиск в уже бегущих функциях предыдущую копию и завершать ее принудительно из обработчика перед запуском следующего более нового экземпляра. Но я этой возможности не нашел.

Есть еще один вариант, создать некий колбек для каждого объекта который бы ждал события и менять ему условия для работы, но ИМХО это может сильно загрузить систему клиента.

Какие у вас будут варианты?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 18-06-2019 17:59 » 

Цитата
в цикле, который занимает менее 1 секунды.
Сколько?

все зависит от того что вы "двигаете"
Может быть все можно решить на эффектах css анимации
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 18-06-2019 19:45 » 

Почему бы не добавить кастомное свойство в элементы и хранить состояние в нем?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
BlueWhite
Интересующийся

il
Offline Offline
Пол: Мужской

« Ответ #3 : 19-06-2019 06:27 » 

Цитата
в цикле, который занимает менее 1 секунды.
Сколько?

все зависит от того что вы "двигаете"
Может быть все можно решить на эффектах css анимации
Про CSS написано в вопросе, про "сколько" - вопрос не по делу - это не важно.

Почему бы не добавить кастомное свойство в элементы и хранить состояние в нем?
Это интересно, как в элемент найденный getElementsByClassName() можно добавить кастомное свойство?

Но все на деле решилось проще.

Дело в том, что по сути когда происходит прокрутка, надо прекращать не один объект, а все, которые бегут.
Т.е. привязка к объекту в задаче стала не нужна.
В результате был введен счетчик и глобальный флаг досрочного выхода.
По флагу если он true организуется выход из цикла асинхронного обработчика, а в обработчике событий добавлен цикл ожидания.

Т.е. вот так.
Код: (Javascript)
stop = true;
do{
   await timer(1); // pause on one ms to run async callbacks
       
}while (countOfRunning > 0);
stop = false;

И собственно все работает.

Логика решения такова, что при рандомной прокрутке по сути надо организовывать конечное состояние по последней активной прокрутке. Не важно как там работало и как было заказано до нее.

Получается отлично плавно и вполне оптимально.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 19-06-2019 07:52 » 

Цитата
Это интересно, как в элемент найденный getElementsByClassName() можно добавить кастомное свойство?
Это JavaScript: element.my_new_field = "zhopa"
Ну или немного культурнее: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/dataset
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
BlueWhite
Интересующийся

il
Offline Offline
Пол: Мужской

« Ответ #5 : 19-06-2019 07:53 » 

Цитата
Это интересно, как в элемент найденный getElementsByClassName() можно добавить кастомное свойство?
Это JavaScript: element.my_new_field = "zhopa"
Ну или немного культурнее: https://developer.mozilla.org/ru/docs/Web/API/HTMLElement/dataset
То, что надо. Если будет необходимость для синхронизации чего-то специфического на странице - пригодится.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 19-06-2019 08:45 » 

Цитата
про "сколько" - вопрос не по делу

Цитата
ИМХО это может сильно загрузить систему клиента.

Цитата
обрабатывается в цикле, который занимает менее 1 секунды. 

setTimeout и setInterval


stop = true;
do{
   await timer(1); // pause on one ms to run async callbacks
       
}while (countOfRunning > 0);
по сути бесконечный цикл


Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
BlueWhite
Интересующийся

il
Offline Offline
Пол: Мужской

« Ответ #7 : 19-06-2019 10:41 » new

Цитата
про "сколько" - вопрос не по делу

Цитата
ИМХО это может сильно загрузить систему клиента.

Цитата
обрабатывается в цикле, который занимает менее 1 секунды. 

setTimeout и setInterval


stop = true;
do{
   await timer(1); // pause on one ms to run async callbacks
       
}while (countOfRunning > 0);
по сути бесконечный цикл


Дружище, ну нельзя быть таким невнимательным.
Сначала ты пропускаешь CSS и причину почему я от него отказываюсь.
Теперь ты пропускаешь, что это не отложенный вызов, а ожидание. И предлагаешь ненужные setInterval и setTimeout.

И пропускаешь вполне четко написанное, что "В результате был введен счетчик и глобальный флаг досрочного выхода. "

Т.е. это не бесконечный цикл, а ожидание обнуления счетчика запущенных асинхронных обработчиков, по флагу stop=true.

Неужели так сложно сначала прочесть потом спрашивать?
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines