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

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

Статус промиса 🆕   |   З’єднайте промиси в ланцюжок


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