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 语句。

范例一

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

<?php
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 语句并没有生成一个值,我们看看如果生成了一个值的会是什么结果

<?php
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')); 会触发生成器的执行,这会一路输出 Foo0 。但是,当执行到 yield 0 时需要触发异常,所以这时候 yield 语句并不会暂停执行,而是继续执行,直到捕获异常,输出 Exception: Test,然后进行下一次迭代,输出 1 然后碰到 yield 1,这时候就会暂停执行了,因为 yield 1 的返回就是 1 ,所以,结果就像输出的那样了。

返回上一级

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.