++ed by:

3 PAUSE users
2 non-PAUSE users.

Joel Berger
and 1 contributors


Mojo::AsyncAwait::Backend::Coro - An Async/Await implementation for Mojolicious using Coro


  use Mojolicious::Lite -signatures;
  use Mojo::AsyncAwait;

  get '/' => async sub ($c) {

    my $mojo = await $c->ua->get_p('https://mojolicious.org');
    my $cpan = await $c->ua->get_p('https://metacpan.org');

    $c->render(json => {
      mojo => $mojo->result->code,
      cpan => $cpan->result->code



As the name suggests, Mojo::AsyncAwait::Backend::Coro is an implementation of the Async/Await pattern, using Mojo::Promise and Coro. See more at Mojo::AsyncAwait.


This implementation relies on Coro which does some very magical things to the Perl interpreter. All caveats that apply to using Coro::State apply to this module as well.

Also note that while a Coro-based implementation need not rely on "await" being called directly from an "async" function, it is currently prohibitied because it is likely that other/future implementations will rely on that behavior and thus it should not be relied upon.


Mojo::AsyncAwait::Backend::Coro provides two keywords (i.e. functions), both exported by default. They are re-exported by Mojo::AsyncAwait if it is the chosen implementation.


  my $sub = async sub { ... };

The async keyword wraps a subroutine as an asynchronous subroutine which is able to be suspended via "await". The return value(s) of the subroutine, when called, will be wrapped in a Mojo::Promise.

The async keyword must be called with a subroutine reference, which will be the body of the async subroutine.

Note that the returned subroutine reference is not invoked for you. If you want to immediately invoke it, you need to so manually.

  my $promise = async(sub{ ... })->();

If called with a preceding name, the subroutine will be installed into the current package with that name.

  async installed_sub => sub { ... };

If called with key-value arguments starting with a dash, the following options are available.


If set to a true value, the subroutine will be installed into the current package. Default is false. Setting this value to true without a -name is an error.


If -install is false, this is a diagnostic name to be included in the subname for debugging purposes. This name is seen in diagnostic information, like stack traces.

  my $named_sub = async -name => my_name => sub { ... };

Otherwise this is the name that will be installed into the current package.

Therefore, passing a bare name as is identical to setting both -name and -install => 1.

  async -name => installed_sub, -install => 1 => sub { ... };

If the subroutine is installed, whether by passing a bare name or the -install option, nothing is returned. Otherwise the return value is the wrapped async subroutine reference.


  my $tx = await Mojo::UserAgent->new->get_p('https://mojolicious.org');
  my @results = await (async sub { ...; return @async_results })->();

The await keyword suspends execution of an async sub until a promise is fulfilled, returning the promise's results. In list context all promise results are returned. For ease of use, in scalar context the first promise result is returned and the remainder are discarded.

If the value passed to await is not a promise (defined as having a then method>), it will be wrapped in a Mojo::Promise for consistency. This is mostly inconsequential to the user.

Note that await can only take one promise as an argument. If you wanted to await multiple promises you probably want "all" in Mojo::Promise or less likely "race" in Mojo::Promise.

  my $results = await Mojo::Promise->all(@promises);


Mojo::Promise, Mojo::IOLoop, Coro, Coro::State