Курс языка программирования Raku / Функциональное, конкурентное, реактивное и веб-программирование / Реактивное программирование / react и whenever
Два таймера
Во всех примерах с react до сих пор использовался
Supply.from-list, который выталкивает все свои значения в
тот же миг, как к нему подключились. Поэтому каждый поток печатался
целиком, прежде чем начинался следующий, — никакого ожидания не было.
Настоящие потоки событий устроены иначе: их значения приходят
растянутыми во времени, и блок react
переплетает их по мере поступления.
Простейший поток с таким поведением — таймер.
Supply.interval($period) выдаёт растущий счётчик —
0, 1, 2, … — раз в $period секунд. Запустите
два таких таймера с разной частотой внутри одного react, и
их значения сплетутся:
react {
whenever Supply.interval(0.3) {
say "tick $_";
}
whenever Supply.interval(0.5, 0.25) {
say "TOCK $_";
}
whenever Promise.in(1.4) {
done;
}
}Типичный запуск печатает:
tick 0
TOCK 0
tick 1
tick 2
TOCK 1
tick 3
tick 4
TOCK 2Быстрый tick срабатывает каждые 0.3
секунды, более медленный TOCK — каждые 0.5,
начиная с четверти секунды (второй аргумент interval и есть
эта начальная задержка). Ни один не ждёт другого: блок
react просто выполняет то тело whenever,
которому соответствует пришедшее значение, поэтому два потока
пересекаются, а не сменяют друг друга.
Поскольку таймеры сами по себе никогда не заканчиваются, выход
обеспечивает третий whenever: Promise.in(1.4)
исполняется через 1,4 секунды, и его тело вызывает done,
завершая блок react. Без него react тикал бы и такал
вечно.
Точное переплетение зависит от того, как лягут задержки, поэтому при следующем запуске строки могут пойти немного иначе, — но такова природа реакции на живые события: вы отвечаете на каждое из них тогда, когда оно происходит.
Навигация по курсу
← whenever и when | Верхний регистр с react →
💪 Или перейдите сразу к упражнениям этого
раздела.