Курс Raku / Функційне, конкурентне, реактивне та веб-програмування / Конкурентне програмування / Промиси

Ланцюжки та комбінування

Обіцянки стають іще потужнішими, коли ви їх поєднуєте. Найпоширеніша потреба — дочекатися кількох одразу. await приймає список обіцянок і повертає їхні результати по порядку:

my @jobs = (start { 1 }), (start { 2 }), (start { 3 });
say await @jobs;     # (1 2 3)
say [+] await @jobs; # 6

Три завдання виконуються конкурентно; await @jobs чекає на всі й повертає (1, 2, 3). Оскільки результати повертаються в тому самому порядку, що й обіцянки, їх можна згортати як завжди.

Роботу можна також зчепити з обіцянкою через .then, який виконує блок-продовження, щойно обіцянка завершиться. Усередині нього .result є значенням початкової обіцянки:

my $p = start { 10 };
my $q = $p.then({ .result * 2 });
say await $q; # 20

$q — це нова обіцянка, що подвоює результат $p. Очікування її дає 20.

Блок не має явного параметра, тож він отримує завершену обіцянку як змінну теми $_ — саме тому голе .result працює: насправді це $_.result. Якщо ви волієте дати цій обіцянці ім’я, скористайтеся гострим блоком:

my $q = $p.then(-> $prev { $prev.result * 2 });

Поводиться це точно так само; $prev є початковою обіцянкою $p, а $prev.result — її значенням.

Маючи start, await та .then, ви можете описувати цілі конвеєри конкурентної роботи: запускати багато завдань, поєднувати їхні результати й будувати нові завдання зі старих — і все це не торкаючись потоку виконання напряму.

Практика

Виконайте 1 тест за змістом цієї теми.

Навігація курсом

Тест — Промиси   |   Тест — Комбінування промисів


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