Awaitable

2018-10-07 09:49 更新
awaitable是async代码中的关键结构。一个等待的是一个一级的Hack对象,表示可能或可能没有完成的可能的异步操作。您await可以等待操作完成。

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功能。


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号