Может ли генератор PHP восстановиться после необработанного исключения? - PullRequest
0 голосов
/ 12 ноября 2018

Рассмотрим эту простую функцию генератора в PHP.

function createAGenerator() {
    echo 'Before First Yield',"\n";
    yield 'First Yield';
    echo 'Before Second Yield',"\n";
    yield 'Second Yield';
    echo 'Before Third Yield',"\n";
    yield 'Third Yield';
}

Если я добавлю в этот генератор метод throw объекта генератора

$generator = createAGenerator();
try {
    $generator->throw(new Exception('Throwing into a Generator'));
} catch(Exception $e) {
    echo 'Caught Exception: ', $e->getMessage(), "\n";
}
echo 'Resuming Main Program Execution',"\n";

, функция генератора перезапуститисключение для меня, чтобы поймать.Все это работает, как я ожидаю.

Однако - мой генератор теперь, кажется, навсегда застрял.Если я попытаюсь перейти к доходности next или send к новому значению, генератор, похоже, просто вернет NULL.Например, следующая программа

<?php
function createAGenerator() {
    echo 'Before First Yield',"\n";
    yield 'First Yield';
    echo 'Before Second Yield',"\n";
    yield 'Second Yield';
    echo 'Before Third Yield',"\n";
    yield 'Third Yield';
}

$generator = createAGenerator();
try {
    $generator->throw(new Exception('Throwing into a Generator'));
} catch(Exception $e) {
    echo 'Caught Exception: ', $e->getMessage(), "\n";
}
echo 'Resuming Main Program Execution',"\n";

var_dump($generator->send('Some Value'));
var_dump($generator->current());
var_dump($generator->next());
var_dump($generator->current());

Возвращает следующий вывод.

Before First Yield
Caught Exception: Throwing into a Generator
Resuming Main Program Execution
NULL
NULL
NULL
NULL

Есть ли способ для генератора восстановить это?Или неперехваченное исключение в генераторе «ломает» этот текущий экземпляр генератора?

1 Ответ

0 голосов
/ 12 ноября 2018

Когда вы генерируете исключение, генератор пропустит прямо до конца функции.Это именно то, что происходит в обычных функциях, если эта функция вызвала что-то, что вызвало исключение.

Ваши две опции:

  1. Чтобы перехватить это в генераторе (или использовать, наконец,).
  2. Чтобы вообще не выбрасывать

Идея вызвать исключение и использовать его как «временную» систему обмена сообщениями, но возобновить нормальную работу, немного странная.Это звучит как злоупотребление исключениями.Возможно, то, что вы пытаетесь достичь, может быть выполнено без исключения.

Если вы пытаетесь смоделировать операцию, которая состоит из нескольких этапов, и каждый из них может по отдельности завершиться с ошибкой или завершиться успешно, одним из вариантов может быть просто датьисключение и не бросай его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...