Как назначить обещание, возвращаемое из get_p, переменной? - PullRequest
4 голосов
/ 20 мая 2019

Я попытался вернуть обещание из подпрограммы, которая содержала некоторые данные, полученные из HTTP-запроса к веб-серверу. Но я не мог позвонить 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;

1 Ответ

5 голосов
/ 20 мая 2019

Все активные соединения, созданные объектом 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 вернулся.

...