W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
Generators(發(fā)電機(jī))提供了一種更緊湊的寫入迭代程序的方法。發(fā)電機(jī)通過在發(fā)電機(jī)和調(diào)用代碼之間來(lái)回傳遞控制來(lái)工作。為了提供迭代的值,代替返回一次或者需要像數(shù)組那樣可以記憶密集的東西,發(fā)電機(jī)可以根據(jù)需要多次產(chǎn)生調(diào)用代碼的值。
Generators可以做Async功能; Async Generators的行為與普通Generators類似,除了每個(gè)產(chǎn)生的值都是Awaitable就是await這樣。
要從Async Generators獲取值或鍵/值對(duì),您可以分別返回HH \ AsyncIterator或HH \ AsyncKeyedIterator。
以下是使用Async實(shí)用功能的示例 usleep()模仿一個(gè)秒針倒計(jì)時(shí)鐘。請(qǐng)注意,在happy_new_year() foreach循環(huán)中我們有語(yǔ)法await as。這是調(diào)用的簡(jiǎn)寫await $ait->next()。
<?hh
namespace Hack\UserDocumentation\Async\Generators\Examples\Iterate;
const SECOND = 1000000; // microseconds
async function countdown(int $from): AsyncIterator<int> {
for ($i = $from; $i >= 0; --$i) {
await \HH\Asio\usleep(SECOND);
// Every second, a value will be yielded back to the caller,
// happy_new_year()
yield $i;
}
}
async function happy_new_year(int $start): Awaitable<void> {
// Get the AsyncIterator that enables the countdown
$ait = countdown($start);
foreach ($ait await as $time) {
// we are awaiting the returned awaitable, so this will be an int
if ($time > 0) {
echo $time . "\n";
} else {
echo "HAPPY NEW YEAR!!!\n";
}
}
}
function run(): void {
\HH\Asio\join(happy_new_year(5)); // 5 second countdown
}
run();
Output
5
4
3
2
1
HAPPY NEW YEAR!!!
你必須使用await as; 否則你不會(huì)得到迭代值。
注意await as就像打電話一樣await $gen->next(); 但是,await as如果可能,您應(yīng)該始終使用。打電話給AsyncGenerator直接的方法很少需要。還要注意,在異步迭代器await as或調(diào)用next()實(shí)際上返回一個(gè)值(而不是void一般的迭代器)。
很少需要直接調(diào)用這些方法。await as應(yīng)該是訪問迭代程序返回值的最常見的用法。
您可以使用Generator發(fā)送值并在Generator上send()引發(fā)異常raise()。
如果您正在做這兩件事情,您的Generator必須返回AsyncGenerator。An AsyncGenenator有三種類型的參數(shù)。第一是關(guān)鍵。第二個(gè)是價(jià)值。第三種是傳遞給的類型send()。
<?hh
namespace Hack\UserDocumentation\Async\Generators\Examples\Send;
const HALF_SECOND = 500000; // microseconds
async function get_name_string(int $id): Awaitable<string> {
// simulate fetch to database where we would actually use $id
await \HH\Asio\usleep(HALF_SECOND);
return str_shuffle("ABCDEFG");
}
async function generate(): AsyncGenerator<int, string, int> {
$id = yield 0 => ''; // initialize $id
// $id is a ?int; you can pass null to send()
while ($id !== null) {
$name = await get_name_string($id);
$id = yield $id => $name; // key/string pair
}
}
async function associate_ids_to_names(
Vector<int> $ids
): Awaitable<void> {
$async_generator = generate();
// You have to call next() before you send. So this is the priming step and
// you will get the initialization result from generate()
$result = await $async_generator->next();
var_dump($result);
foreach ($ids as $id) {
// $result will be an array of ?int and string
$result = await $async_generator->send($id);
var_dump($result);
}
}
function run(): void {
$ids = Vector {1, 2, 3, 4};
\HH\Asio\join(associate_ids_to_names($ids));
}
run();
Output
array(2) {
[0]=>
int(0)
[1]=>
string(0) ""
}
array(2) {
[0]=>
int(1)
[1]=>
string(7) "GEFDBAC"
}
array(2) {
[0]=>
int(2)
[1]=>
string(7) "FBGEACD"
}
array(2) {
[0]=>
int(3)
[1]=>
string(7) "GBCDFAE"
}
array(2) {
[0]=>
int(4)
[1]=>
string(7) "FCBGEAD"
}
這是如何將異常引發(fā)到Async Generators。
<?hh
namespace Hack\UserDocumentation\Async\Generators\Examples\Raise;
const HALF_SECOND = 500000; // microseconds
async function get_name_string(int $id): Awaitable<string> {
// simulate fetch to database where we would actually use $id
await \HH\Asio\usleep(HALF_SECOND);
return str_shuffle("ABCDEFG");
}
async function generate(): AsyncGenerator<int, string, int> {
$id = yield 0 => ''; // initialize $id
// $id is a ?int; you can pass null to send()
while ($id !== null) {
$name = "";
try {
$name = await get_name_string($id);
$id = yield $id => $name; // key/string pair
} catch (\Exception $ex) {
var_dump($ex->getMessage());
$id = yield 0 => '';
}
}
}
async function associate_ids_to_names(
Vector<int> $ids
): Awaitable<void> {
$async_generator = generate();
// You have to call next() before you send. So this is the priming step and
// you will get the initialization result from generate()
$result = await $async_generator->next();
var_dump($result);
foreach ($ids as $id) {
if ($id === 3) {
$result = await $async_generator->raise(
new \Exception("Id of 3 is bad!")
);
} else {
$result = await $async_generator->send($id);
}
var_dump($result);
}
}
function run(): void {
$ids = Vector {1, 2, 3, 4};
\HH\Asio\join(associate_ids_to_names($ids));
}
run();
Output
array(2) {
[0]=>
int(0)
[1]=>
string(0) ""
}
array(2) {
[0]=>
int(1)
[1]=>
string(7) "GEAFBCD"
}
array(2) {
[0]=>
int(2)
[1]=>
string(7) "GFEDBAC"
}
string(15) "Id of 3 is bad!"
array(2) {
[0]=>
int(0)
[1]=>
string(0) ""
}
array(2) {
[0]=>
int(4)
[1]=>
string(7) "FGCAEBD"
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: