Raku-Kurs / Funktionale, nebenläufige, reaktive und Web-Programmierung / Nebenläufige Programmierung / Promises
Vows 🆕
Wenn Sie selbst $p.keep(...) aufrufen, könnte jeder, der
$p besitzt, es erledigen. Manchmal wollen Sie das
Gegenteil: Nur der Code, der das Ergebnis erzeugt, soll das
Promise erledigen dürfen, während alle anderen bloß darauf warten
dürfen. Diese Trennung ist ein Gelöbnis (Vow).
Promise.new gibt Ihnen ein Promise; darauf
.vow aufzurufen überreicht ein Vow — das
alleinige Recht, dieses Promise zu erfüllen oder zu brechen. Von da an
ist das Promise als nur lesbar gedacht: Es wird über das Gelöbnis
erledigt. Die übliche Form ist ein Erzeuger, der das Gelöbnis für sich
behält und nur das Promise zurückgibt:
sub after($seconds) {
my $p = Promise.new;
my $v = $p.vow; # take the settle-right
start {
sleep $seconds;
$v.keep("done after $seconds s"); # settle it through the vow
}
return $p; # callers get only the read side
}
my $job = after(0.2);
say $job.status; # Planned
say await $job; # done after 0.2 sDas Gelöbnis zu nehmen macht das Promise wirklich nur lesbar: Von
diesem Augenblick an werden $p.keep und
$p.break abgelehnt, denn das Gelöbnis besitzt nun das
alleinige Recht, es zu erledigen.
my $p = Promise.new;
my $v = $p.vow;
$p.keep(1); # dies: Access denied to keep/break this Promise; already vowedDer Aufrufer kann das Promise also await-en,
.then daran hängen oder seinen .status prüfen,
aber er kann es nicht erledigen — das kann nur der Inhaber des
Gelöbnisses. So machen Bibliotheken aus auf Rückrufen und Ereignissen
gestützten Schnittstellen gewöhnliche Promises: ein Promise erzeugen,
sein Gelöbnis halten und es aus dem Rückruf heraus erfüllen, wenn das
Ereignis endlich eintritt.
Genau das tut auch start hinter den Kulissen für Sie —
es erzeugt ein Promise, behält das Gelöbnis für sich und erledigt das
Promise mit dem Wert des Blocks (oder bricht es, wenn der Block stirbt).
Das Promise und sein Gelöbnis von Hand zu erzeugen erlaubt Ihnen
schlicht, dasselbe zu tun, wenn das Ergebnis nicht aus einem einzelnen
Codeblock kommt.
Kursnavigation
← Der Status eines Promise 🆕 | Verketten Sie ein Promise →
💪 Oder springen Sie direkt zu den Übungen dieses
Abschnitts.