如何在不暂停整个脚本的情况下在 AnyEvent 回调中 "sleep"?

How do you "sleep" in an AnyEvent callback without pausing the whole script?

我专门使用 AnyEvent::Inotify::Simple(使用 EV 作为后端)来监视文件事件。所以我有一个处理程序回调,在特定情况下,我需要 "pause" 才能继续。 sleep 显然会停止一切(因此在 sleep 完成之前不会处理其他事件),所以我尝试使用 alarm 但是如果发生相同的情况再次设置警报,原始警报(因此它的 $SIG{ALRM} 子警报)被忽略,只有 "new" 警报是 运行.

#sleep-based approach (definitely a no-go)
sub handler {
    my ( $self, $event, $file ) = @_;
    #do some stuff
    ...
    if( $some_condition_exists ) {
        sleep(3);
        #now that we've waited, if some change occurred then do stuff
        if ( $new_change_occurred ) {
            #do some new stuff
        }
    }
    return;
}

#alarm -based approach (still a no-go when callback is called again while original alarm is still counting down)
sub handler {
    my ( $self, $event, $file ) = @_;
    #do some stuff
    ...
    if( $some_condition_exists ) {
        $SIG{ALRM} = sub {
             #now that we've waited, if some change occurred then do stuff
             if ( $new_change_occurred ) {
                 #do some new stuff
             }
        }
        alarm(3);
    }
    return;
}

有什么建议吗?我所需要的只是一种在继续异步处理新的 inotify 事件的同时使回调暂停的方法。

使用 AnyEvent::timer 时,请确保跟踪它 returns 的守卫对象。我通常将它们存储在全局中。

如果将其分配给超出范围的变量,计时器将被取消。

my $guards;

sub handler {
    my ( $self, $event, $file ) = @_;
    #do some stuff
    ...
    if( $some_condition_exists ) {
        $guards->{$file} = AE::timer 3,0,sub {
             #now that we've waited, if some change occurred then do stuff
             if ( $new_change_occurred ) {
                 #do some new stuff
             }
        };
    }
    return;
}