4

我试图从一个包含从 HTTP 请求获得的一些数据到 Web 服务器的子程序中返回一个承诺。但我无法调用then结果。缩小范围后,似乎不可能将返回的承诺分配给get_p变量,然后将其用作承诺。

这是一个例子。我原以为这两个请求完全相同,但只有第二个请求运行 then 块中的代码。

有人可以解释一下有什么区别,如果我想在子程序then之外链接更多方法,我应该如何从子程序返回一个承诺?

#!/usr/bin/perl -w

use strict;
use warnings;
use utf8;
use 5.024;

use Data::Dumper;
use Mojo::IOLoop;
use Mojo::UserAgent;

my $promise = Mojo::UserAgent->new->get_p('http://example.com');
$promise->then(sub {
    my $tx = shift;
    warn 'Using variable';
    warn $tx->result->body;
})->wait;

Mojo::UserAgent->new->get_p('http://example.com')
->then(sub {
    my $tx = shift;
    warn 'Not using variable';
    warn $tx->result->body;
})->wait;
4

1 回答 1

4

当 UA 对象被销毁时,由 UA 对象创建的所有活动连接都将关闭。承诺不引用 UA 对象,因此您必须确保 UA 对象不会被破坏。

#!/usr/bin/perl -w

use strict;
use warnings;
use utf8;
use 5.024;

use Mojo::IOLoop;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new;

my $promise = $ua->get_p('http://example.com');
$promise->then(sub {
    my $tx = shift;
    warn 'Using variable';
    warn $tx->result->body;
})->wait;

$ua->get_p('http://example.com')
->then(sub {
    my $tx = shift;
    warn 'Not using variable';
    warn $tx->result->body;
})->wait;

由于 Perl 使用引用计数来进行垃圾收集,因此不会因为认为对象一旦没有引用对象就被销毁而犯错。实际上,一个对象可以一直存在到它成为未引用的语句结束为止。(这是用于补偿未计算堆栈引用的机制的副作用。)

当您只使用单个语句时,您的测试有效,因为 UA 对象一直存在到语句结束,因此在wait返回之后。

于 2019-05-20T16:40:09.873 回答