Курс языка программирования Raku / Функциональное, конкурентное, реактивное и веб-программирование / Конкурентное программирование / Промисы
Обещания (Vow) 🆕
Когда вы сами вызываете $p.keep(...), уладить промис
может любой, кто держит $p. Иногда нужно обратное:
улаживать промис должен только тот код, который производит
результат, а всем остальным позволено лишь дожидаться. Это разделение и
есть обещание (vow).
Promise.new даёт вам промис; вызов .vow у
него возвращает Vow — единоличное право исполнить или
сломать этот промис. С этого момента промис предполагается доступным
только для чтения: улаживают его через обещание. Обычная форма —
производитель, который держит обещание при себе и возвращает только
промис:
sub after($seconds) {
my $p = Promise.new;
my $v = $p.vow; # забираем право улаживать
start {
sleep $seconds;
$v.keep("done after $seconds s"); # улаживаем через обещание
}
return $p; # вызывающим достаётся только сторона для чтения
}
my $job = after(0.2);
say $job.status; # Planned
say await $job; # done after 0.2 sВзятие обещания делает промис по-настоящему доступным только для
чтения: с этого момента $p.keep и $p.break
отвергаются, потому что единоличное право улаживать теперь принадлежит
обещанию.
my $p = Promise.new;
my $v = $p.vow;
$p.keep(1); # умирает: Access denied to keep/break this Promise; already vowedИтак, вызывающая сторона может дождаться промиса через
await, надстроить над ним .then или проверить
его .status, но уладить его не может — на это способен лишь
держатель обещания. Именно так библиотеки превращают API на обратных
вызовах и событиях в обычные промисы: создают промис, держат его
обещание и исполняют его изнутри обратного вызова, когда событие наконец
наступает.
Ровно это start и делает за вас за кулисами: он создаёт
промис, оставляет обещание себе и улаживает промис значением блока (или
ломает его, если блок умер). Создание промиса и его обещания вручную
просто позволяет сделать то же самое, когда результат приходит не из
одного блока кода.
Навигация по курсу
← Статус промиса 🆕 | Соедините промисы в цепочку →
💪 Или перейдите сразу к упражнениям этого
раздела.