Perl 执行星号回调的顺序



>我有一个代码如下:

 1  sub do_leave {
 2
 3    my ($asterisk, $event) = @_;
 4    my $join_id;
 5    my $id = $astman->send_action({ Action    => 'Getvar',
 6                                    Variable  => 'join_id',
 7                                    Channel   => $event->{'Channel'},
 8                                  }, &get_value, undef, $join_id);
 9
10    sleep(2);
11    say "join_id is: $join_id";
12
13    my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?";
14    my $sth = $dbh->prepare($sql);
15    $sth->execute($join_id);
16  }
17
18  sub get_value {
19    my ($ast, $resp, $ref_join_id) = @_;
20    for my $key (keys %$resp) {
21      if ($key eq "PARSED") {
22        $$ref_join_id = $resp->{$key}{"Value"};
23      }
24    }
25  }

我正在使用星号::AMI模块从星号AMI获取信息。每当有人离开会议时,都会调用do_leave Sub。我的问题是get_value do_leave中的所有语句之后执行的回调。如何使get_value回调在第 10 行之前执行。send_action中的变量$join_id是回调的第三个参数。我需要在 sql 语句之前$join_id变量。

要对脚本进行最小的更改,

sub do_leave {
  my ($asterisk, $event) = @_;
  my $join_id;
  my $sub = sub {
    get_value(@_);
    say "join_id is: $join_id";
    my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?";
    my $sth = $dbh->prepare($sql);
    $sth->execute($join_id);
  };
  my $id = $astman->send_action({ Action    => 'Getvar',
                                  Variable  => 'join_id',
                                  Channel   => $event->{'Channel'},
                                }, $sub, undef, $join_id);
  # sleep(2);
}
我没有

使用过Asterisk::AMI,但我假设send_action方法采用回调方法的原因是结果异步返回。你不能保证这需要多长时间。

一个快速简便的解决方案是将数据库更新放在回调函数中,如下所示:

sub do_leave {
  my ($asterisk, $event) = @_;
  my $get_value = sub {
    my ($ast, $resp, $ref_join_id) = @_;
    for my $key (keys %$resp) {
        if ($key eq "PARSED") {
            my $ref_join_id = $resp->{$key}{"Value"};
            my $sql = "UPDATE conference_log SET duration=(TIMESTAMPDIFF(SECOND, (SELECT start_conf), NOW())), end_conf=(NOW()) WHERE id=?";
            my $sth = $dbh->prepare($sql);
            $sth->execute($join_id);
        }
    }
  };
  my $id = $astman->send_action({ Action    => 'Getvar',
                                  Variable  => 'join_id',
                                  Channel   => $event->{'Channel'},
                                }, $get_value);
}

请注意,我使用了一个匿名 sub,分配给一个变量,这将允许您在外部 do_leave sub 和回调 sub 之间共享变量(这称为闭包)。但是,在这种情况下,可能不需要它,因为没有共享变量。

相关内容

  • 没有找到相关文章

最新更新