Add Promise::all (#6152)

This commit is contained in:
ShockedPlot7560
2024-02-06 13:42:24 +01:00
committed by GitHub
parent 20837c9894
commit 6bb84bc46c
3 changed files with 171 additions and 0 deletions

View File

@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\promise;
use function count;
use function spl_object_id;
/**
@@ -57,4 +58,53 @@ final class Promise{
//rejected or just hasn't been resolved yet
return $this->shared->state === true;
}
/**
* Returns a promise that will resolve only once all the Promises in
* `$promises` have resolved. The resolution value of the returned promise
* will be an array containing the resolution values of each Promises in
* `$promises` indexed by the respective Promises' array keys.
*
* @param Promise[] $promises
*
* @phpstan-template TPromiseValue
* @phpstan-template TKey of array-key
* @phpstan-param non-empty-array<TKey, Promise<TPromiseValue>> $promises
*
* @phpstan-return Promise<array<TKey, TPromiseValue>>
*/
public static function all(array $promises) : Promise{
if(count($promises) === 0){
throw new \InvalidArgumentException("At least one promise must be provided");
}
/** @phpstan-var PromiseResolver<array<TKey, TPromiseValue>> $resolver */
$resolver = new PromiseResolver();
$values = [];
$toResolve = count($promises);
$continue = true;
foreach($promises as $key => $promise){
$promise->onCompletion(
function(mixed $value) use ($resolver, $key, $toResolve, &$values) : void{
$values[$key] = $value;
if(count($values) === $toResolve){
$resolver->resolve($values);
}
},
function() use ($resolver, &$continue) : void{
if($continue){
$continue = false;
$resolver->reject();
}
}
);
if(!$continue){
break;
}
}
return $resolver->getPromise();
}
}