diff --git a/lib/Future/functions.php b/lib/Future/functions.php index a294b6e..954be89 100644 --- a/lib/Future/functions.php +++ b/lib/Future/functions.php @@ -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 */ - return $futures; + return $values; } diff --git a/test/Future/AllTest.php b/test/Future/AllTest.php index 1140789..601ccd5 100644 --- a/test/Future/AllTest.php +++ b/test/Future/AllTest.php @@ -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