Курс языка программирования 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 filedie происходит в фоновом потоке, но исключение
путешествует вместе с промисом и выныривает на await. Там
его перехватывает try, оставляя $result
неопределённым, а ошибку — в $!; так что сбой в
конкурентной работе обрабатывается точно так же, как любое другое
исключение. Поэтому ожидание — не только про получение значения: это ещё
и момент, когда конкурентная работа воссоединяется с основным потоком
выполнения, как с результатами, так и с ошибками.
Практика
Пройдите 2 теста по содержанию этой темы.
Навигация по курсу
← await | Тест — await →
💪 Или перейдите сразу к упражнениям этого
раздела.