1. 程式人生 > >Perl6多線程3: Promise start / in / await

Perl6多線程3: Promise start / in / await

await font erl 跟著 art logs pan 什麽 主程序

創建一個Promise 並自動運行:

my $p = Promise.start({say Hello, Promise!});

如果把代碼改成如下, 我們會發現什麽也沒打印:

my $p = Promise.start({sleep 2;say Hello, Promise!});

匿名函數 sleep 2 秒, 這時, 它還沒運行完, 主程序就退出了, 這裏 promise也跟著退出, 所以什麽也沒打印。

我們可以改寫成這樣:

my $p = Promise.start({sleep 2;say Hello, Promise!});
sleep 3;

是不是覺得有點不太好?因為你有時並不知道程序什麽時候運行完成。

記得上面說過 return 方法, 會阻塞直到 Promise完成, 可以改成這樣:

my $p = Promise.start({sleep 2;say Hello, Promise!});
$p.result;

其實還有一個方式, 那就是:

await

代碼可以改寫成這樣:

my $p = Promise.start({sleep 3;say Hello, P});
my $p1 = Promise.start({say Hello, P1});

await $p;

如果我們創建好一個 promise 後, 不想讓它馬上運行, 而是要讓他過多少秒後再運行, 有沒有辦法呢?

這時可以用:

Promise.in

這個 in 會返回一個新的 Promise, 並在多少秒後執行 用這個Promise($p)去執行 then方法(這個then前面介紹過):

my $p = Promise.in(3);
$p.then( -> $p_ {say $p.status;say Hello, promise.in!});

上面代碼並不能打印, 因為主程序已退出。

可能你想到了 await, 改寫如下:

my $p = Promise.in(3);
$p.then( -> $p_ {say $p.status;say Hello, promise.in!
}); #await $p; await $p;

可以正常打印, 但有問題, 問題就是:

這個 Promise.in會在多少秒後, 返回一個 Promise($p), 之後在自身調用 kept方法, $p看到 keep方法了, 會去調用 then, 流程就是這樣。

我們最後在等待的是: $p。

但你想想, 這個 await 會等到 kept時就會退出, 在它退出時那個 $p.then才剛運行。 這就是問題所在。

下面是驗證代碼:

my $p = Promise.in(3);
$p.then( -> $p_ {sleep 3;say $p.status;say Hello, promise.in!});
#await $p;
await $p;

我雖然 await 了, 但沒能打印。因為主程序已退出了。

上一篇已說過, $p.then 方法會返回一個新的 Promise, 我們可以在這個新的 Promise 身上調用 await 方法即可, 如下:

my $p = Promise.in(3);
my $p1 = $p.then( -> $p_ {sleep 3;say $p.status;say Hello, promise.in!});
#await $p;
await $p1;

結果如下:

C:\p6>perl6 scan_dir.p6
Kept
Hello, promise.in!

C:\p6>

我們還可以讓很多代碼塊一起執行, 當所有代碼塊執行完成後才退出, 或者其中一個代碼塊執行完成後就立即退出:

1. allof
2. anyof

Perl6多線程3: Promise start / in / await