Awaitable
Awaitable
通过Hack接口表示Awaitable。虽然有几个类实现Awaitable,但是没有必要关心他们的实现细节。Awaitable是您需要的唯一接口。
从一个异步函数返回的类型是Awaitable<T>,其中T是最后的结果类型(例如,int等候的值的)。
async function foo(): Awaitable<int> {...}
$x = foo(); // $x will be an Awaitable<int>
$x = await foo(); // $x will be an int
<?hh
namespace Hack\UserDocumentation\Async\Awaitables\Examples\AwaitableReturn;
async function f(): Awaitable<int> {
return 2;
}
// You call f() and get back an Awaitable<int>
// Once the function is finish executing and you await the awaitable (or in
// this case explicitly join since this call is not in an async function) to get
// the explicit result of the function call, you will get back 2.
var_dump(\HH\Asio\join(f()));
Output
int(2)
所有async功能必须返回Awaitable。async因此,调用函数将产生一个实现该Awaitable接口的对象,并且必须await或join从该对象获取操作的最终结果。当您await暂停当前任务,直到与Awaitable句柄关联的操作完成,其他任务可以自由继续执行。join是类似的,但它阻止所有其他操作完成,直到Awaitable返回。
Awaiting
在大多数情况下,你会喜欢await的Awaitable,这样当你阻塞操作完成其他任务可以执行。但是请注意,只有async功能可以控制其他异步,所以await可能只能在一个async功能中使用。对于其他位置,如main块,您将需要使用join,本节后面将会介绍。
批处理Awaitables
很多时候你会await一个人Awaitable,得到结果,继续前进。
<?hh
namespace Hack\UserDocumentation\Async\Awaitables\Examples\SingleAwaitable;
async function foo(): Awaitable<int> {
return 3;
}
async function single_awaitable_main(): Awaitable<void> {
$aw = foo(); // awaitable of type Awaitable<int>
$result = await $aw; // an int after $aw completes
var_dump($result);
}
single_awaitable_main();
Output
int(3)
你通常会看到类似的东西await f();,结合了waiting的Awaitable和检索Awaitable的结果。上面的例子将其分离出来用于说明目的。
其他的时候,你会收集一堆Awaitable和await他们的一切,然后继续前进。
在这里,我们使用HH\Asio命名空间中的两个内置异步协助函数之一,以便将一堆Awaitable时间批量化在一起await:
- HH\Asio\v():具有连续整数键的awaitables列表的索引列表
- HH\Asio\m():具有整数或字符串键的awaitables图的关联映射
<?hh
namespace Hack\UserDocumentation\Async\Awaitables\Examples\MultipleAwaitables;
async function quads(float $n): Awaitable<float> {
return $n * 4.0;
}
async function quads_m(): Awaitable<void> {
$awaitables = array(
'five' => quads(5.0),
'nine' => quads(9.0),
);
$results = await \HH\Asio\m($awaitables);
var_dump($results['five']); // float(20)
var_dump($results['nine']); // float(36)
}
quads_m();
Output
float(20)
float(36)
Join
有时你希望得到一个结果出来的awaitable的,当你在函数不是 async。对于这一点HH\Asio\join(),需要一个Awaitable和块才能解决一个结果。
这意味着不能等待来自全局范围(也称为伪域)的异步函数的调用,必须加入。
<?hh
namespace Hack\UserDocumentation\Async\Awaitables\Examples\Join;
async function get_raw(string $url): Awaitable<string> {
return await \HH\Asio\curl_exec($url);
}
function join_main(): void {
$result = \HH\Asio\join(get_raw("http://www.example.com"));
var_dump(substr($result, 0, 10));
}
join_main();
Output
string(10) "<!doctype "
你不应该调用join()
一个async
函数。这将打破目前async
的awaitable,任何依赖将同步完成,阻止任何其他awaitable其轨迹运行。只是await
在一个async
功能。