Bagaimana saya bisa membatalkan janji di Raku?

9

Saya tahu saya bisa menjadwalkan Promiseuntuk disimpan dalam jumlah waktu tertentu

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

tetapi bagaimana saya bisa menjadwalkannya untuk dilanggar? Secara khusus, saya memikirkan janji yang akan "habis", sehingga masih ada waktu untuk dijaga atau kalau tidak akan gagal.

Saya bisa melakukan ini dengan yang lain Promise, seperti:

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

Tapi ini terasa agak ... sia-sia. Apakah ada cara yang lebih baik untuk melakukan ini?

jja
sumber

Jawaban:

10

Pola umum adalah menulis sesuatu seperti ini:

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

Itu tidak memanifestasikan dirinya sebagai rusak Promise, meskipun itu tidak semuanya buruk (karena Anda perlu membedakan pembatalan vs kesalahan dalam banyak kasus, jadi Anda masih harus melakukan pencocokan pada jenis pengecualian). Anjak piutang ini juga memiliki keuntungan yang $the-promisetidak harus Anda dapatkan / pertahankan.

Orang juga bisa membungkusnya dengan sesuatu seperti ini:

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

Yang lagi-lagi akan bekerja dengan apa pun $promise, meneruskan hasil atau pengecualian, dan membuang pengecualian batas waktu sebaliknya.

Yang perlu diingat dengan semua ini adalah bahwa mereka tidak benar-benar mempengaruhi pembatalan pekerjaan yang sedang berlangsung. Itu mungkin tidak penting, atau mungkin penting. Jika yang terakhir, Anda mungkin ingin:

  • A Promiseyang Anda gunakan untuk menyampaikan pembatalan telah terjadi; Anda menyimpannya saat membatalkan, dan polling dalam kode yang akan melakukan pembatalan
  • Untuk melihat menggunakan Supplyparadigma sebagai gantinya, di mana ada model pembatalan (menutup keran).
Jonathan Worthington
sumber
3
Terima kasih. Ini bermanfaat. Dan paling tidak itu mendorong pulang bahwa janji itu murah (!) Dan menggunakannya baik seperti yang Anda sarankan, atau bagaimana saya awalnya memikirkan, tidak apa-apa. Masih terasa seperti harus ada (lebih?) Cara langsung untuk mengatakan "jika janji ini tidak disimpan dalam X detik maka anggap itu rusak". Saya mendapatkan bahwa itu tidak masuk akal dalam semua kasus, tetapi saya pikir itu pasti masuk akal dalam beberapa kasus.
jja
3
Itu mungkin akan datang di masa depan, namun mungkin hanya ketika kita memiliki semacam Promiseketentuan pembatalan di inti juga, karena semantiknya akan diikat dengan itu.
Jonathan Worthington