我有一个生成器,它将值的集合传递给方法并生成结果。调用的方法可能会返回异常。发生这种情况时,我希望异常转到调用生成器来处理异常的代码,然后继续循环生成器。
为了说明这一点,下面是一个生成器的示例,它将产生1
,抛出一个\Exception
,然后产量3
.
/** @var \Generator $gen */
$gen = function () {
for ($i = 1; $i <= 3; $i++) {
if ($i == 2) {
throw new \Exception('Exception thrown for 2');
}
yield $i;
}
};
这是我尝试运行此代码的示例,以便我可以让它产生结果3
$g = $gen();
var_export($g->current());
echo "\n";
try {
$g->next();
var_export($g->current());
echo "\n";
} catch (\Exception $e) {
echo $e->getMessage() . "\n";
}
try {
$g->next();
var_export($g->current());
echo "\n";
} catch (\Exception $e) {
echo $e->getMessage() . "\n";
}
以下是上述代码的输出。
1
Exception thrown for 2.
NULL
所以反复调用next()
什么都不做并且current()
将返回NULL
,我希望生成器继续通过异常,这样我就可以得到3
.
在生成器内部抛出异常会完全关闭它,这就是为什么它在第三次迭代时返回“NULL”。如果你试试$g->valid()
抛出异常后你会得到false
作为结果。
生成器内部抛出的所有异常也应该在生成器内部捕获和处理,您甚至可以抛出它们从外部进入发电机用于处理使用$g->throw()
方法。欲了解更多信息检查文档 https://secure.php.net/manual/en/generator.throw.php
However,你想要实现的目标是可能的。你可以yield
异常,而不是抛出。这样你就不会关闭生成器,并且可以在外面处理异常。
试试这个代码:
$gen = function () {
for ($i = 1; $i <= 3; $i++) {
// If something wrong happens
if ($i == 2) {
// Instead throwing the exception yield it
// that way we don't close the generator
yield new \Exception('Exception thrown for 2');
} else {
yield $i;
}
}
};
并用以下方法测试它:
$g = $gen();
for ($i = 0; $i < 3; $i++) {
$current = $g->current();
// Instead of catching, check if the yielded value is Exception
if ($current instanceof \Exception) {
// Handle the exception directly
// or throw it with throw $current to handle it in normal try-catch block
echo $current->getMessage() . "\n";
} else {
echo $current . "\n";
}
$g->next();
}
给你结果:
1
Exception thrown for 2
3
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)