php generator 风雪,PHP Generator::throw() 方法

PHP Generator::throw() 方法用于手动引发生成器的一个异常。

( PHP 5 >= 5.5.0, PHP 7 )

这个方法就有意思了,使用 Generator::throw() 方法,我们可以在外部生成一个异常,并将该已成发送给生成器,生成器会在下次遇到 yield 语句时触发这个异常。

方法原型

PHP Generator::throw() 方法的原型如下

public mixed Generator::throw ( Throwable $exception )

从原型中可以看出,该方法接收一个异常 $exception ,并将异常发送给生成器,并继续执行生成器。(因为生成器需要下次遇到 yield 时才会触发这个异常 )。

这个方法的行为和在生成器内部使用 throw $exception 语句替换当前 yield 表达式时的行为相同。

如果在调用此方法时生成器已关闭,则异常将在调用者的上下文中抛出。

参数说明

参数

说明

$exception

要发送给生成器的异常

返回值

该方法返回已经 yield 的值。

你不是不很奇怪为什么还会返回一个值? 难道不是调用就会立即触发异常么 ?

前面章节我忘记说了,生成器看起来是在另一个线程中异步执行的代码。一旦执行,如果要停下来,只能是再次碰到 yield 语句。

范例一

简单的生成一个异常,并将该异常发送给生成器

function gen() {

echo "Foo\n";

try {

yield;

} catch (Exception $e) {

echo "Exception:{$e->getMessage()}\n";

}

echo "Bar\n";

}

$gen = gen();

$gen->throw(new Exception('Test'));

运行结果如下

Foo

Exception: Test

Bar

上面这段代码,当调用 gen() 创建一个生成器时并不会执行任何生成器内的函数。直到调用 $gen->throw(new Exception('Test')); 将一个异常发送给这个生成器。

因为该函数同时会触发生成器的执行,所以,就会开始输出 Foo ,但运行到 yield 时发现就要抛出一个异常,于是就会抛出一个异常,抛出的异常会被 try catch 捕获到,于是会输出 Exception: Test ,然后函数继续执行,就会输出 Bar

范例二

在上面这个范例中,yield 语句并没有生成一个值,我们看看如果生成了一个值的会是什么结果

function gen() {

echo "Foo\n";

for ( $i = 0; $i < 10; $i++ )

{

try {

echo $i,"\n";

yield $i;

} catch (Exception $e) {

echo "Exception:{$e->getMessage()}\n";

}

}

echo "Bar\n";

}

$gen = gen();

$ret = $gen->throw(new Exception('Test'));

echo $ret,"\n";

运行结果如下

Foo

0

Exception: Test

1

1

是不是对执行结果感到很疑惑 ?

首先,要记牢一件事:生成器只有运行到一个 yield 语句时才会停止执行。

所以当调用 $gen->throw(new Exception('Test')); 会触发生成器的执行,这会一路输出 Foo 和 0 。但是,当执行到 yield 0 时需要触发异常,所以这时候 yield 语句并不会暂停执行,而是继续执行,直到捕获异常,输出 Exception: Test,然后进行下一次迭代,输出 1 然后碰到 yield 1,这时候就会暂停执行了,因为 yield 1 的返回就是 1 ,所以,结果就像输出的那样了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值