Как стать автором
Обновить

Комментарии 10

Очень интересно. Но ничего не понятно.

Вопрос, который меня беспокоит больше всего - каким образом yield возвращает значение?
Это стандартное поведение в php или это добавляет кто-то из RoadRunner, ReactPHP и Workflow PHP SDK?

Понимаю, что смысл статьи немного в другом, но, глядя на этот код, возникает много вопросов о том, стоит ли писать на php то, для чего php не создавался. Надеюсь никого не обидеть и донести свою мысль правильно. Да, на php мы все любим и сейчас можно написать неблокирующий или многопоточный код, но:

  1. код в результате выглядит так, словно он написан на каком-то совершенно новом языке. Экономии на изучении нового языка не так много

  2. Большую часть библиотек, написанных не для конкретного решения (swoolee или ReactPHP) переиспользовать нельзя - они будут либо течь, либо блокировать io, либо сохранять стейт между запросами.

  3. Язык не заточен для этих задач и не обладает встроенным инструментарием для облегчения разработки таких решений. Например - сможет ли хоть один статический анализатор для php проверить корректность вызова:
    $saga->addCompensation(fn() => yield $booking->cancelHotel());
    Какой тут тип у параметра метода addCompensation()? Просто callable? Есть ли правило для phpstan которое проверит, что замыкание является генератором?

yield - это ключевое слово в php, которое работает почти как return, но в отличии от return может приостановить выполнение функции, а не полностью остановить её. И говорит нам о том, что мы имеем дело с генератором (\Generator). Пример:

function getValues(): \Generator
{
	yield 1;
	yield 2;
	yield 3;
}

function getValuesArray(): array
{
	return [1, 2, 3];
}

foreach(getValues() as $int) {}
foreach(getValuesArray() as $int) {}

оба foreach практически идентичны в действиях, но yield в генераторе позволяет получить значение и приостановить генератор, в то время как массив будет передан сразу полностью.

P.S. В этом видео то же, что и в цикле статей. Но формат может будет понятней =)

Спасибо за ответ, но что такое yield я знаю. Чего я не понимаю - почему в коде результат yield присваивается переменной.

<?php

function gen()
{
    $date = yield new \DateTime();
    var_dump($date); // NULL yield не возращает значение
}

foreach(gen() as $date) {
}

Yield позволяет как передавать данные из генератора наружу, так и получать данные в генератор из внешнего кода.

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

генераторы используются в некоторых подходах для реализации асинхронного выполнения на php

Да, стандартное. Если речь про $hi = yield, то Generator::send
Если про return $hi . $bye;, то Generator::getReturn


Вообще генераторы — это такая коробка с сюрпризами, что да, голову надо перестраивать. У меня вот пока не очень получается. Но с другой строны, не всё же на крудах сидеть?

Привет, постараюсь ответить на часть вопросов.

1) Все сделано на стандартном PHP. :)

2) А активити (где и находится основная нагрузка) можно использовать что угодно, и оно даже может течь. :) В workflow - не надо, это чистый бизнес код.

3) Если вы посмотрите на код Saga - это 150 строчек хелпер кода над стандартным функционалом СДК, никто не мешает (а даже, поощряет) делать свои, более строго-типизированные, обертки.

тема интересная, но хотелось бы полноценный пример.не совсем понятно как это все вместе связывается.

планируются ли еще статьи на эту тему?

Невероятно, до рашен it дошел temporal ??

Зарегистрируйтесь на Хабре, чтобы оставить комментарий