多路复用回调

Dal*_*aen 10 perl asynchronous

假设我在一个应用程序中有许多任务,可以按任何顺序完成.我需要在所有任务完成后运行一些代码.如果这很重要,应用程序在AnyEvent下运行,但没有Coro.

从某种程度上说,AnyEvent$cv->begin/$cv->end让我想要什么.但是,我希望有更细粒度的控制.例如,我想无法两次"完成"任务.从所有任务中收集数据的能力也很不错.

当然,这可以做到.设置许多共享哈希的回调; 任务完成时从该哈希中删除键; 当散列为空时调用megacallback.我想知道是否有更文明的方式,也许是一些CPAN模块?

例如,这是一个可以满足我需求的虚构API.

#!/usr/bin/perl -w 
use strict;

use Some::Module;

# Set goals
my $cb = Some::Module->new( sub { say 'BOOM!' } );
$cb->begin( qw(foo bar) );

# Much later, as tasks start getting done
$cb->end( foo => 42 );       # "return" value from task 'foo'
$cb->begin( 'baz' );         # can add more tasks, why not
$cb->end( 'bar' );           # just finish task 'bar'
# still waiting for 'baz' to finish at this point

# Finally, last hanging task is done
$cb->end( baz => 137 );      # BOOM!
# at this point, sub {}->( { foo=>42, bar=>undef, baz=>137 } ) 
#     has been called
Run Code Online (Sandbox Code Playgroud)

另见我的perlmonks问题.

它有这样的东西吗?

Leo*_*erd 3

您可能需要考虑Future

具体来说,为了等待许多事情完成,您可以使用Future->needs_all或类似的:

my @things = ... # generate Futures to represent each thing

Future->needs_all( @things )
  ->on_done( sub {
     # some code here when all the things are done 
  });
Run Code Online (Sandbox Code Playgroud)

或者,您也可以尝试Async::MergePoint,它提供的 API 更接近您的想法:

my $mp = Async::MergePoint->new( needs => [qw( foo bar )] );
$mp->close( on_done => sub {
   # some code here when all the things are done
});

$mp->done( foo => $value );
$mp->done( bar => );
Run Code Online (Sandbox Code Playgroud)