Perl Mojolicious:链接Promises

kq0g1dla  于 2023-04-06  发布在  Perl
关注(0)|答案(1)|浏览(121)

在一个Mojolicious控制器中,我想链接两组Promise。第一组(例如delDB1delDB2)从源中删除,完成后,第二组(例如addBD1addDB2)添加到源中。
你会添加另一个then吗?如果是,我如何传递新的Promises集?
将调用嵌套在内部似乎不正确。

my @promise;
foreach my $code (\&delDB1, \&delDB2) {
  my $prom = Mojo::Promise->new;
  Mojo::IOLoop->subprocess(
    sub {
      return $code->($number);
    },
    sub {
      my ($subprocess, $err, @res) = @_;
      return $prom->reject($err) if $err;
      $prom->resolve(@res);
    },
  );
  push @promise, $prom;
}

Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
Mojo::Promise->all(@promise)
  ->then(
  sub {
    my ($delDB1response, $delDB2response) = map {$_->[0]} @_;
    ### Nest a call for another set of promises?
    $app->render(openapi=>{messages=>"success"});
  })->catch(
    sub ($err) {
    warn "### Something went wrong: $err";
  })->wait;
i7uq4tfw

i7uq4tfw1#

你的问题不清楚。我认为你想要以下内容:
1.试试
1.启动delDB1
1.启动delDB2
1.等待两者完成。
1.启动addDB1
1.启动addDB2
1.等待两者完成。
1.呈现成功的响应。
1.接住
1.呈现失败响应。
这可以通过以下方式实现:

Mojo::Promise
->all( delDB1_async(), delDB2_async() )
->then(sub {
   return Mojo::Promise->all( addDB1_async(), addDB2_async() );
})
->then(sub {
   # Render successful response here...
})
->catch(sub {
   # Render failure response here...
})
->wait;

在上面的例子中,_async函数应该返回一个promise。
如果我们为了讨论而给予promise命名,代码就变成了

my $promise1 = delDB1_async();
my $promise2 = delDB2_async();

my $promise3 = Mojo::Promise->all( $promise1, $promise2 );
my $promise4 = $promise3->then(sub {
   my $promise5 = addDB1_async();
   my $promise6 = addDB2_async();

   my $promise7 = Mojo::Promise->all( $promise5, $promise6 );

   return $promise7;
});

my $promise8 = $promise4->then(sub {
   # Render successful response here...
});

my $promise9 = $promise8->catch(sub {
   # Render failure response here...
});

$promise9->wait;

关键部分是当$promise7满足时,$promise4也满足,并且具有相同的值。
但假设你想
1.试试
1.开始时间:
1.启动delDB1
1.等待它完成。
1.启动addDB1
1.等待它完成。
1.开始时间:
1.启动delDB2
1.等待它完成。
1.启动addDB2
1.等待它完成。
1.等待两者完成。
1.呈现成功的响应。
1.接住
1.呈现失败响应。
这可以通过以下方式实现:

Mojo::Promise
->all(
    delDB1_async()->then(sub { return addDB1_async() }),
    delDB2_async()->then(sub { return addDB2_async() }),
)
->then(sub {
   # Render successful response here...
})
->catch(sub {
   # Render failure response here...
})
->wait;

示例delDB1_async

sub delDB1_async {
   return Mojo::Promise->new(sub {
      my ( $resolve, $reject ) = @_;
      Mojo::IOLoop->subprocess(
         sub {
            ...
         },
         sub {
            my ( $subprocess, $err, @res ) = @_;
            $reject->( $err ) if $err;
            $resolve->( @res );
         }
      );
  });
}

->new传递一个sub会更好,因为该代码的异常会导致promise被拒绝。如果代码意外抛出异常,这是很好的。
...除了Mojo::Promise违反了它声称遵守的规范。所以如果代码意外抛出异常,你现在就完蛋了。

相关问题