Курс 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


💪 Або перейдіть одразу до вправ цього розділу.