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

创建一个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
时间: 2024-08-25 21:30:23

Perl6多线程3: Promise start / in / await的相关文章

Perl6多线程2: Promise new/keep/bread/status/result

来源于个人理解的翻译. 创建一个 promise: my $p = Promise.new; 可以打印运行 的Promise 状态: my $p = Promise.new(); $p.then({say 'hello, world'}); say $p.status; 上面的promise创建好后, 当 $p 状态为 kept或broken 时, 会执行 then 里面的 匿名函数. 但是, 上面的$p状态总是为: Plannd. 所以, 那个 hello, world 总是不能打印. 那怎么

node.js异步控制流程 回调,事件,promise和async/await

写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. 接下来是解析,为什么我会有这样的结论 首先是回调,理解上最简单,就是我把任务分配出去,当你执行完了我就能从你那里拿到结果执行相应的回调, 这里演示一个对setTimeout的封装,规定时间后打印相应结果并执行回调函数 并且这个函数传给回调函数的参数符合node标准,第一个为error信息,如果出错e

Perl6多线程1: new / run

先看一个小例子: sub A($name = 3) { #默认参数 say $name; } sub B(:name($name)) { #默认参数为 any say $name; } A(); A(100); B(); B(name => 'root'); 这是正常的调用方式. 再看如下代码: sub A($name) { #默认参数 say $name; } sub B() { say 'BBBBBBBB'; } A(1); B; B(); &A(123); &B(); 可以看到

callback vs async.js vs promise vs async / await

需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = function (code) { if (code) { return true; } else { return false; } } let readFileA = function (callback) { if (read(1)) { return callback(null, "111");

Promise和Async/Await用法整理

1.Promise 1.简介 Promise,简单来说就是一个容器,里面保存着某个未来才会结束的时间(通常是一个异步操作的结果) Promise对象的基本语法: new Promise((resolve,reject) => { //..... }); 从语法上来说,Promise是一个对象,从它可以获取异步操作的消息. 基本语法: let p = new Promise((resolve,reject) => { //... resolve('success') }); p.then(res

重构:从Promise到Async/Await

摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前,我就在鼓吹Async/Await替代Promise的6个理由,似乎还招致了一些批评.然而,直到最近,我才真正开始进行代码重构,抛弃Promise,全面使用Async/Await.因为,Node 8终于LTS了! Async/Await真的比Promise好吗? 是的是的. 这些天,我大概重构了10

异步 callback vs promise vs async/await

1. callback var fn1=function(){console.log("func1")} var fn2=function(fn){ setTimeout(function(){ console.log("func2") fn() //不能写fn,这只是函数名,要写fn()才是触发 },500)}var fn3=function(){console.log("func3")} //函数名作为参数传入fn2 fn1()fn2(fn3

理解异步之美:Promise与async await(一)

你可能会放出一个怪物 异步与同步相比,最难以掌控的就是异步的任务会什么时候完成和完成之后的回调问题, 难以掌控的触发状态,让你自己写的代码当时还可以读懂,但是过几天.半个月之后如果不重新盘一边逻辑,你哪知道哪个内容会先执行,借用这么一个例子 listen( "click", function handler(evt){ setTimeout( function request(){ ajax( "http://some.url.1", function respon

用promise和async/await分别实现红绿灯

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con