Awaitable

2018-10-07 09:49 更新
awaitable是async代碼中的關(guān)鍵結(jié)構(gòu)。一個(gè)等待的是一個(gè)一級(jí)的Hack對(duì)象,表示可能或可能沒(méi)有完成的可能的異步操作。您await可以等待操作完成。

Awaitable

通過(guò)Hack接口表示Awaitable。雖然有幾個(gè)類實(shí)現(xiàn)Awaitable,但是沒(méi)有必要關(guān)心他們的實(shí)現(xiàn)細(xì)節(jié)。Awaitable是您需要的唯一接口。

從一個(gè)異步函數(shù)返回的類型是Awaitable<T>,其中T是最后的結(jié)果類型(例如,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因此,調(diào)用函數(shù)將產(chǎn)生一個(gè)實(shí)現(xiàn)該Awaitable接口的對(duì)象,并且必須await或join從該對(duì)象獲取操作的最終結(jié)果。當(dāng)您await暫停當(dāng)前??任務(wù),直到與Awaitable句柄關(guān)聯(lián)的操作完成,其他任務(wù)可以自由繼續(xù)執(zhí)行。join是類似的,但它阻止所有其他操作完成,直到Awaitable返回。

Awaiting

在大多數(shù)情況下,你會(huì)喜歡await的Awaitable,這樣當(dāng)你阻塞操作完成其他任務(wù)可以執(zhí)行。但是請(qǐng)注意,只有async功能可以控制其他異步,所以await可能只能在一個(gè)async功能中使用。對(duì)于其他位置,如main塊,您將需要使用join,本節(jié)后面將會(huì)介紹。

批處理Awaitables

很多時(shí)候你會(huì)await一個(gè)人Awaitable,得到結(jié)果,繼續(xù)前進(jìn)。

<?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)

你通常會(huì)看到類似的東西await f();,結(jié)合了waiting的Awaitable和檢索Awaitable的結(jié)果。上面的例子將其分離出來(lái)用于說(shuō)明目的。

其他的時(shí)候,你會(huì)收集一堆Awaitable和await他們的一切,然后繼續(xù)前進(jìn)。

在這里,我們使用HH\Asio命名空間中的兩個(gè)內(nèi)置異步協(xié)助函數(shù)之一,以便將一堆Awaitable時(shí)間批量化在一起await:

  • HH\Asio\v():具有連續(xù)整數(shù)鍵的awaitables列表的索引列表
  • HH\Asio\m():具有整數(shù)或字符串鍵的awaitables圖的關(guān)聯(lián)映射
<?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

有時(shí)你希望得到一個(gè)結(jié)果出來(lái)的awaitable的,當(dāng)你在函數(shù)不是 async。對(duì)于這一點(diǎn)HH\Asio\join(),需要一個(gè)Awaitable和塊才能解決一個(gè)結(jié)果。

這意味著不能等待來(lái)自全局范圍(也稱為偽域)的異步函數(shù)的調(diào)用,必須加入。

<?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 "

你不應(yīng)該調(diào)用join()一個(gè)async函數(shù)。這將打破目前async的awaitable,任何依賴將同步完成,阻止任何其他awaitable其軌跡運(yùn)行。只是await在一個(gè)async功能。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)