是否可以从另一个诺言中终止一个诺言的代码块? [英] Is it possible to terminate a promise's code block from another promise?

查看:70
本文介绍了是否可以从另一个诺言中终止一个诺言的代码块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了这个测试程序:

await Promise.anyof(
  Promise.allof((^5).map: {start { sleep 10; say "done $_" } }),
  Promise.in(5).then: { say 'ouch' }
);
sleep 10;

当第二个诺言超时时,它会打印 ouch并等待,但第一个诺言的代码会退出块仍在运行。再过五秒钟后,它的五个过程结束并打印'done':

When the second promise times out it prints 'ouch' and the await exits, but the first promise's code block is still running. After five more seconds its five processes end and print 'done':

$ ./test1.p6
ouch
done 0
done 1
done 2
done 3
done 4

我试图终止将第一个promise赋给变量,然后从第二个promise调用 .break 方法,但是它没有

I tried to terminate the first promise assigning it to a variable and then calling the .break method from the second promise, but it doesn't work.

是否有一种方法可以杀死第一个诺言及其开始的其他五个子诺言?

Is there a way to kill the first promise and the other five sub-promises it started?

推荐答案

您必须以某种方式告诉该过程它不必完成。

You have to somehow tell the process that it doesn't have to finish.

my $cancel = Cancellation.new;

await Promise.anyof(
  Promise.allof(
    (^5).map: {
      last if $cancel.cancelled;

      start {
        sleep 10;
        say "done $_" unless $cancel.cancelled
      }
    }
  ),
  Promise.in(5).then: {
    $cancel.cancel;
    say 'ouch'
  }
);






如果您想要类似 Promise.in()可以取消,让我们从查看现有代码


If you want something like Promise.in() that can be cancelled, let's start by looking at the existing code.

method in(Promise:U: $seconds, :$scheduler = $*SCHEDULER) {
    my $p   := self.new(:$scheduler);
    my $vow := $p.vow;
    $scheduler.cue({ $vow.keep(True) }, :in($seconds));
    $p
}

请注意 $ scheduler.cue 是一个取消。

为了简单起见,我将在一个类中包装一个Promise和一个Cancellation。 br>
(我不想重新实现每个方法)。

I am just going to wrap a Promise, and a Cancellation in a class for simplicity.
(I don't want to reimplement every method).

class Cancellable-Timer {
    has Promise      $.Promise;
    has              $!vow;
    has Cancellation $!cancel;

    method !SET-SELF ( $!promise, $!vow, $!cancel ){
        self
    }

    method in (::?CLASS:U: $seconds, :$scheduler = $*SCHEDULER) {
        my $p   := Promise.new(:$scheduler);
        my $vow := $p.vow;
        my $cancel = $scheduler.cue({ $vow.keep(True) }, :in($seconds));
        self.bless!SET-SELF($p,$vow,$cancel);
    }

    method cancel ( --> Nil ) {
        # potential concurrency problem
        if $!Promise.status == Planned {
            $!cancel.cancel;          # cancel the timer
            $!vow.break("cancelled"); # break the Promise
        }
    }

    method cancelled () {
        # Ignore any concurrency problems by using the Promise
        # as the sole source of truth.
        $!Promise.status ~~ PromiseStatus::Broken
    }
}

my $timer = Cancellable-Timer.in(1);
my $say = $timer.Promise.then: *.say;
Promise.in(0.1).then: {$timer.cancel};
await $say;

请注意,以上课程只是初稿。

Note that the above class is just a rough first draft.

这篇关于是否可以从另一个诺言中终止一个诺言的代码块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆