smscr / simple-coroutine-for-reactphp
Requires
- php: >=7.1
- react/promise: ~2.2
Requires (Dev)
- react/event-loop: ^1.1
This package is auto-updated.
Last update: 2024-10-30 01:37:29 UTC
README
Description
The function coroutine accepts as an argument $resolvable value and resolves it as callable or promose with support for yield from instances of \Generator, and returns a promise either resolved with the final value that cannot be resolved further or rejected with the first \Throwable that wasn't caught in the chain
Install via composer:
"require": {
"smscr/simple-coroutine-for-reactphp": "^1.0.0"
}
Details:
The first argument of the function is $resolvable value
If second argument $call = true, then would be attempted first to resolve (through possible Promise chains) the $resolvable value to a callable. If a callable is detected, it is invoked and it's return value is resolved (through possible Promise chains). This applies recursively.
If $resolvable is a Generator, or a Generator is found by resolving $resolvable or by resolving a result of invoked callable, then the Generator is processed as a coroutine
If the $resolvable is an array, then it would be mapped to resolved values, including, if $call = true, then all entries of the array will be attempted to resolve to a callable or a Generator, each, independently, and this applies recursively.
When a Generator is processed as a coroutine, this function is applied to any value yielded by a Generator, that means, a callable (if $call = true), a Generator, a Promise or an array of any of such will be resolved by the rules above if yielded by a Generator resolved by the rules above
After the value yielded by a Generator is resolved, the result is sent to the Generator If any errors occur during resolving a value, it is thrown into a Generator Once a Generator returns a value, it is resolved by the rules above
The resolved value that was returned by a Generator is a result of the Promise returned by this function, possibly as an element of an array of such results
Usage:
use React\Promise;
use React\Promise\PromiseInterface;
use function Shavshukov\Coroutine\coroutine;
function resolvePromises(PromiseInterface $promise1, PromiseInterface $promise2, PromiseInterface $promise3, callable $resultsCallback)
{
try {
// instead of Promise\resolve($promise1)->then(function ($result1) {...});
$result1 = yield $promise1;
// instead of Promise\all([$promise2, $promise3])->then(function ($results23) {...});
$results23 = yield [
$promise2,
$promise3
];
$generator = function () use ($result1, $results23) {
$results = [];
$results[] = yield $result1;
foreach ($results23 as $result) {
$results[] = yield $result;
}
return $results;
};
// coroutine will call this generator function and resolve it
$results123 = yield $generator;
// if you pass a \Generator instance it will also resolve it
$onceMoreResults123 = yield $generator();
// if a PromiseInterface resolves to a \Generator, it will also resolve the \Generator value
// this would also work with array of promises that resolve to \Generators
// and this would work recursively
$secondTimeMoreResults123 = yield Promise\resolve()->then(function () use ($generator) {
return $generator();
});
// values will be passed to the $resultsCallback, not promises or \Generator instances
$finalResult = yield $resultsCallback($secondTimeMoreResults123);
return $finalResult;
} catch (\Throwable $e) {
// return an exception if caught
return $e;
}
}
// coroutine function accepts promises, values, \Generator instances and arrays of such, and always returns a promise
coroutine(function () {
$return = yield resolvePromises(Promise\resolve(1), Promise\resolve(2), Promise\resolve(3), function (array $secondTimeMoreResults123) {
return implode(', ', $secondTimeMoreResults123);
});
return $return;
})->then(function (string $finalResult1) {
// will print 1, 2, 3
echo $finalResult1 . PHP_EOL;
});
coroutine(function () {
$return = yield resolvePromises(Promise\resolve(1), Promise\resolve(2), Promise\resolve(3), function (array $secondTimeMoreResults123) {
throw new \Exception('Sometines, something happens...');
});
return $return;
})->then(function (\Throwable $exception) {
// will print "Something happened! Sometines, something happens..."
echo "Something happened! {$exception->getMessage()}" . PHP_EOL;
});