Як я можу відкласти обіцянку в Раку?


9

Я знаю, що можу запланувати час, Promiseякий потрібно зберігати протягом певного часу

my $promise = Promise.in($seconds);

але як я можу запланувати його розрив? Зокрема, я маю на увазі обіцянку, яка "закінчиться", так що вона має дотримуватися певного часу, інакше вона не виконає.

Я можу це зробити з іншим Promise, як-от так:

my $promise = Promise.new;
...
Promise.in($seconds).then: { $promise.break };

Але це відчуває себе трохи ... марно. Чи є кращий спосіб зробити це?

Відповіді:


10

Поширений зразок - написати щось подібне:

await Promise.anyof($the-promise, Promise.in(10));
if $the-promise {
    # it finished ahead of the timeout
}
else {
    # it timed out
}

Це не проявляється як зламане Promise, хоча це не все погано (оскільки у будь-якому випадку потрібно відрізняти скасування від помилки, тому все одно доведеться виконати відповідність типу винятків). Цей факторинг також має перевагу в тому, що$the-promise він не повинен бути тим, що у вас є доступ, щоб утримати / перервати.

Можна також обернути це в щось подібне:

class TimedOut is Exception {}
sub timeout($promise, $time) {
    start {
        await Promise.anyof($promise, Promise.in($time));
        $promise ?? await($promise) !! die(TimedOut.new)
    }
}

Котрий знову працюватиме з будь-яким $promise, передає результат або виняток, а іншим чином викидає вичерпаний виняток.

Слід пам’ятати про все це в тому, що вони фактично не роблять жодного скасування незавершеного виробництва. Це може не мати значення, або це може бути важливо. Якщо останнє, ви, ймовірно, захочете:

  • А Promise, Який використовується для передачі скасування відбувся; ви зберігаєте його під час скасування та запитуєте його в коді, який буде робити скасування
  • Подивитись на використання Supplyпарадигми замість того, де є модель скасування (закриття крана).

3
Дякую. Це корисно. І принаймні це доводить додому, що обіцянки дешеві (!), І використовувати їх як ви пропонуєте, або, як я спочатку думав, це нормально. Все ще відчувається, що повинен бути (більше?) Прямий спосіб сказати, "якщо ця обіцянка не була дотримана протягом X секунд, тоді вважайте її порушеною". Я вважаю, що це не матиме сенсу у всіх випадках, але я думаю, що в деяких це має сенс.
jja

3
Це, мабуть, настане в майбутньому, однак, ймовірно, лише тоді, коли у нас є якісь Promiseположення про скасування в основі, оскільки його семантика буде дещо пов'язана з тими.
Джонатан Уортінгтон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.