From 9a8d6bf29c0c8c9ac0eb7933f3bafae97099db60 Mon Sep 17 00:00:00 2001 From: voldenet Date: Thu, 29 May 2025 12:51:30 +0200 Subject: [PATCH 1/2] Add "andthen" and "orelse" to Promise.rakudoc --- doc/Type/Promise.rakudoc | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/doc/Type/Promise.rakudoc b/doc/Type/Promise.rakudoc index b27d558d4..e0a67d3d8 100644 --- a/doc/Type/Promise.rakudoc +++ b/doc/Type/Promise.rakudoc @@ -230,6 +230,55 @@ to the C<&code>. say $after.result; # OUTPUT: «Kept␤2 seconds are over␤result␤» +=head2 method andthen + + method andthen(Promise:D: &code) + +Schedules a piece of code to be run after the invocant has been kept. +If the invocant is broken, the C<&code> is skipped and the returned promise +will be broken with the same cause. The C is passed as an argument +to the C<&code>. + + # Successful chain + my $p = Promise.kept(42); + my $after = $p.andthen(-> $orig { + my $res = $orig.result; # Get result from original promise + say "Got $res"; + $res + 10 + }); + await $after; + say $after.result; # OUTPUT: «Got 42␤52␤» + + # Broken promise skips the code + my $broken = Promise.broken(X::AdHoc.new(payload => "Error")); + my $unrun = $broken.andthen(-> $orig { say "never runs" }); + try await $unrun; + say $unrun.cause.message; # OUTPUT: «Error␤» + +=head2 method orelse + + method orelse(Promise:D: &code) + +Schedules a piece of code to be run after the invocant has been broken. +If the invocant is kept, the C<&code> is skipped and the returned promise +will be kept with the same result. The C is passed as an argument +to the C<&code>. + + # Error recovery + my $broken = Promise.broken(X::AdHoc.new(payload => "DB Error")); + my $recovered = $broken.orelse(-> $orig { + my $err = $orig.cause; # Get exception from original promise + "Using cached data because of {$err.message}" + }); + await $recovered; + say $recovered.result; # OUTPUT: «Using cached data because of DB Error␤» + + # Kept promise skips the code + my $kept = Promise.kept(42); + my $unchanged = $kept.orelse(-> $orig { "recovered" }); + await $unchanged; + say $unchanged.result; # OUTPUT: «42␤» + =head2 method keep multi method keep(Promise:D: \result = True) From 3ea5074fc912ba863eb08f7f124cfc556404ecb0 Mon Sep 17 00:00:00 2001 From: voldenet Date: Thu, 29 May 2025 13:00:59 +0200 Subject: [PATCH 2/2] Improve examples in 'andthen' and 'orelse' Promise.rakudoc Use awaited result directly instead of $promise.result --- doc/Type/Promise.rakudoc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/Type/Promise.rakudoc b/doc/Type/Promise.rakudoc index e0a67d3d8..ee203067b 100644 --- a/doc/Type/Promise.rakudoc +++ b/doc/Type/Promise.rakudoc @@ -246,8 +246,7 @@ to the C<&code>. say "Got $res"; $res + 10 }); - await $after; - say $after.result; # OUTPUT: «Got 42␤52␤» + say await $after; # OUTPUT: «Got 42␤52␤» # Broken promise skips the code my $broken = Promise.broken(X::AdHoc.new(payload => "Error")); @@ -270,14 +269,12 @@ to the C<&code>. my $err = $orig.cause; # Get exception from original promise "Using cached data because of {$err.message}" }); - await $recovered; - say $recovered.result; # OUTPUT: «Using cached data because of DB Error␤» + say await $recovered; # OUTPUT: «Using cached data because of DB Error␤» # Kept promise skips the code my $kept = Promise.kept(42); my $unchanged = $kept.orelse(-> $orig { "recovered" }); - await $unchanged; - say $unchanged.result; # OUTPUT: «42␤» + say await $unchanged; # OUTPUT: «42␤» =head2 method keep