异步编程是一种编程的设计模式。它允许多个独立的任务协同工作,在同一线程内传递控制权。从最小依赖和任务交互的角度来看,这些任务是相互独立的。异步编程最常用于I/O读写。
Hack使用async
和await
两个关键词支持异步编程。async
声明异步函数。await
会挂起一个异步函数的执行,直到await
代表的异步操作的结果可以访问。await
可以使用的函数的返回值为实现了Awaitable<T>
的对象。
<?hh
classFoo{}
classBar {
publicfunctiongetFoo(): Foo {
returnnew Foo();
}
}
async functiongen_foo(int$a): Awaitable<?Foo> {
if ($a === 0) {
returnnull;
}
$bar = await gen_bar($a);
if ($bar !== null) {
return$bar->getFoo();
}
returnnull;
}
async functiongen_bar(int$a): Awaitable<?Bar> {
if ($a === 0) {
returnnull;
}
returnnew Bar();
}
gen_foo(4);
gen_foo()
前有async
关键字,因此它是一个异步函数。异步函数总是返回一个实现了Awaitable<T>
的对象(通常具体的实现是WaitHandle<T>
,不过几乎在所有场合都推荐使用Awaitable<T>
接口。
调用gen_foo()
会引入一些有趣的属性,这些都是异步函数特有的。异步函数可能会贪婪地执行异步函数体部分。调用gen_bar()
首先返回一个Awaitable
对象,这个对象在执行之中可能完成,也可能不完成。如果它没有完成,那么gen_foo()
会挂起执行,否则gen_foo()
会析构结果并继续贪婪执行。在await
声明以外的执行不会被挂起。异步编程框架会记录所有应该完成的异步操作。