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


💪 Или преминете направо към упражненията в този раздел.