iterated promises (Mojo::Promise::Role::Repeat)

22 views
Skip to first unread message

Roger Crew

unread,
Oct 1, 2019, 10:12:21 AM10/1/19
to Mojolicious
So I've uploaded Mojo::Promise::Role::Repeat to CPAN.

This adds a single method to Mojo::Promise
  
$done_p = $promise->repeat(sub{...})

which is essentially equivalent to

$done_p = $promise->then(sub{...})->then(sub{...})->then(sub{...})->then(sub{...}) #... forever

The promise returned represents the end of the chain off at infinity, meaning
  • if any instance of the handler sub{...} dies or returns a rejected promise
    $done_p is rejected with the same @reason(s).
  • if any instance of sub {...} calls $_->(@values) -- $_ is bound to an escape function that does not return --
    $done_p is resolved with @values (and execution of everything else in the loop is abandoned).
and these are the only ways out of the loop.  If a handler run returns normally or returns a resolved promise, the return values become the arguments for the next iteration (as one would expect for consecutive then()s).

The function bound to $_ also works from inside of nested handlers/loops (though you'll want to stash it in a lexical if you're going to do that since $_ will probably be set to something different by the time the nested handler runs).  Meaning you can do stuff like this

$ua->get_p(...)->repeat(sub{
   
my $break = $_;
   
...
   $ua
->get_p(...)->repeat(sub {
       
...
       $ua
->get_p(...)->then(sub {
          
...
          $break
->('bye') if (condition);
          
...
       
}
       
...
   
}
   
...
})

Anyway it's up.  Enjoy.

Reply all
Reply to author
Forward
0 new messages