1
0
mirror of https://github.com/danog/amp.git synced 2025-01-22 21:31:18 +01:00

Fix all() with iterable

Key order is not guaranteed, like the other Future combinators. This does not affect array unpacking.
This commit is contained in:
Aaron Piotrowski 2021-09-20 18:49:52 -05:00
parent 493e59e8ab
commit 2a53328982
No known key found for this signature in database
GPG Key ID: ADD1EF783EDE9EEB
2 changed files with 19 additions and 6 deletions

View File

@ -113,7 +113,8 @@ function settle(iterable $futures, ?CancellationToken $token = null): array {
}
/**
* Awaits all futures to complete or aborts if any errors.
* Awaits all futures to complete or aborts if any errors. The returned array keys will be in the order the futures
* resolved, not in the order given by the iterable. Sort the array after resolution if necessary.
*
* @template Tk of array-key
* @template Tv
@ -125,11 +126,12 @@ function settle(iterable $futures, ?CancellationToken $token = null): array {
*/
function all(iterable $futures, CancellationToken $token = null): array
{
$values = [];
// Future::iterate() to throw the first error based on completion order instead of argument order
foreach (Future::iterate($futures, $token) as $k => $future) {
$futures[$k] = $future->await();
foreach (Future::iterate($futures, $token) as $index => $future) {
$values[$index] = $future->await();
}
/** @var array<Tk, Tv> */
return $futures;
return $values;
}

View File

@ -8,7 +8,6 @@ use Amp\Future;
use Amp\TimeoutCancellationToken;
use PHPUnit\Framework\TestCase;
use Revolt\EventLoop\Loop;
use function Amp\delay;
use function Amp\Future\all;
class AllTest extends TestCase
@ -29,7 +28,19 @@ class AllTest extends TestCase
Loop::delay(0.01, fn() => $deferred->complete(1));
self::assertSame([1, 2], all([$deferred->getFuture(), Future::complete(2)]));
self::assertSame([1 => 2, 0 => 1], all([$deferred->getFuture(), Future::complete(2)]));
}
public function testArrayDestructuring(): void
{
$deferred = new Deferred;
Loop::delay(0.01, fn() => $deferred->complete(1));
[$first, $second] = all([$deferred->getFuture(), Future::complete(2)]);
self::assertSame(1, $first);
self::assertSame(2, $second);
}
public function testTwoFirstThrowing(): void