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

Очікування промиса

await приймає обіцянку, чекає її завершення й повертає її результат:

my $p = start { 7 * 6 };
say await $p; # 42

Програма зупиняється на await лише настільки, наскільки потрібно, а потім продовжується зі значенням, яке дала обіцянка.

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

my @jobs = (start { 5 }), (start { 10 }), (start { 15 });
say await @jobs;     # (5 10 15)
say [+] await @jobs; # 30

Завдання виконуються конкурентно, але await @jobs не повертається, доки не завершиться кожне з них. Кожен результат тоді стоїть на тій самій позиції, що й його обіцянка в @jobs, — байдуже, яке завдання завершилося першим.

Якщо очікувану обіцянку було зламано — її блок кинув виняток, — await повторно кидає цей виняток у точці await. Це означає, що помилки у фоновій роботі виринають там, де ви на неї чекаєте, тож ви можете обробити їх звичними try / CATCH із частини про винятки:

my $p = start { die 'no such file' };

my $result = try await $p;
say $result // "the job failed: $!";

Це друкує:

the job failed: no such file

die стається у фоновому потоці, але виняток мандрує разом з обіцянкою й вискакує на await. try перехоплює його там, лишаючи $result неозначеним, а помилку — у $!, тож невдача в конкурентній роботі обробляється точно як будь-який інший виняток. Отже, очікування — це не лише про отримання значення; це мить, коли конкурентна робота знову вливається в основний потік виконання, і з результатами, і з помилками.

Практика

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

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

await   |   Тест — await


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