Курс 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 робить за вас за лаштунками:
він створює обіцянку, лишає зарок собі й владнує обіцянку значенням
блоку (або ламає її, якщо блок помирає). Створення обіцянки та її зароку
вручну просто дозволяє вам зробити те саме, коли результат походить не з
єдиного блоку коду.
Навігація курсом
← Статус промиса 🆕 | З’єднайте промиси в ланцюжок →
💪 Або перейдіть одразу до вправ цього розділу.