<?php namespace Amp\Future; use Amp\Cancellation; use Amp\CompositeException; use Amp\CompositeLengthException; use Amp\Future; /** * Unwraps the first completed future. * * If you want the first future completed without an error, use {@see any()} instead. * * @template T * * @param iterable<Future<T>> $futures * @param Cancellation|null $cancellation Optional cancellation. * * @return T * * @throws CompositeLengthException If {@code $futures} is empty. */ function awaitFirst(iterable $futures, ?Cancellation $cancellation = null): mixed { foreach (Future::iterate($futures, $cancellation) as $first) { return $first->await(); } throw new CompositeLengthException('Argument #1 ($futures) is empty'); } /** * Awaits the first successfully completed future, ignoring errors. * * If you want the first future completed, successful or not, use {@see awaitFirst()} instead. * * @template Tk of array-key * @template Tv * * @param iterable<Tk, Future<Tv>> $futures * @param Cancellation|null $cancellation Optional cancellation. * * @return Tv * * @throws CompositeException If all futures errored. * @throws CompositeLengthException If {@code $futures} is empty. */ function awaitAny(iterable $futures, ?Cancellation $cancellation = null): mixed { $result = awaitAnyN(1, $futures, $cancellation); return $result[\array_key_first($result)]; } /** * Awaits the first N successfully completed futures, ignoring errors. * * @template Tk of array-key * @template Tv * * @param positive-int $count * @param iterable<Tk, Future<Tv>> $futures * @param Cancellation|null $cancellation Optional cancellation. * * @return non-empty-array<Tk, Tv> * * @throws CompositeException If too many futures errored. * @throws CompositeLengthException If {@code $futures} is empty. */ function awaitAnyN(int $count, iterable $futures, ?Cancellation $cancellation = null): array { if ($count <= 0) { throw new \ValueError('Argument #1 ($count) must be greater than 0, got ' . $count); } $values = []; $errors = []; foreach (Future::iterate($futures, $cancellation) as $index => $future) { try { $values[$index] = $future->await(); if (\count($values) === $count) { return $values; } } catch (\Throwable $throwable) { $errors[$index] = $throwable; } } if (\count($values) + \count($errors) < $count) { throw new CompositeLengthException('Argument #2 ($futures) contains too few futures to satisfy the required count of ' . $count); } /** * @var non-empty-array<Tk, \Throwable> $errors */ throw new CompositeException($errors); } /** * Awaits all futures to complete or error. * * This awaits all futures without aborting on first error (unlike {@see await()}). * * @template Tk of array-key * @template Tv * * @param iterable<Tk, Future<Tv>> $futures * @param Cancellation|null $cancellation Optional cancellation. * * @return array{array<Tk, \Throwable>, array<Tk, Tv>} */ function awaitAll(iterable $futures, ?Cancellation $cancellation = null): array { $values = []; $errors = []; foreach (Future::iterate($futures, $cancellation) as $index => $future) { try { $values[$index] = $future->await(); } catch (\Throwable $throwable) { $errors[$index] = $throwable; } } return [$errors, $values]; } /** * 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 completion if necessary. * * This is equivalent to awaiting all futures in a loop, except that it aborts as soon as one of the futures errors * instead of relying on the order in the iterable and awaiting the futures sequentially. * * @template Tk of array-key * @template Tv * * @param iterable<Tk, Future<Tv>> $futures * @param Cancellation|null $cancellation Optional cancellation. * * @return array<Tk, Tv> Unwrapped values with the order preserved. */ function await(iterable $futures, ?Cancellation $cancellation = null): array { $values = []; // Future::iterate() to throw the first error based on completion order instead of argument order foreach (Future::iterate($futures, $cancellation) as $index => $future) { $values[$index] = $future->await(); } /** @var array<Tk, Tv> */ return $values; } __halt_compiler();----SIGNATURE:----CllPlRweZNWAac2h4Wd2Ar4TDzRfhYhKj2NQI7+gs2S/sYZHQ2TWLffJs2t3T/qMdnlDKYiQxSf/w4dHgaHU6Tw+FsV3TSXzisVt3e+Ot/KmtAS8T2Zbi6Hi5g0lXYuhpythrOdYyPzhcUTWnsq5wD9QPZvk7nsFXb0MDY8imBysyvkgszki7SvBBNe2FBIHZHwp7SZT9L1usRYnZaAECbGjJBgT24AgtsKwL6biWGorzewiJsD/9qQbz6VW2Gnp/uyhPsy2Bszne8nb2/lFg/EZVCiG3G2o0SqHf1QelE8QXQPewm6OL/p4X0r9+M6wM+EKzp9Iomq0lCmoRk/cbD13B9WxJyHtsQZZV/wopGS6c/ZROmlkd3xnL+w5qvn2qIs/L6e8kXrHVKyITJxdcI/grr0YbY9o5YHvyCHHe5bEjXIe9+GyWVaM3Qbw94kcZvVLNBfMwRcs391NI113KQCbaBBP+X5/UdDm//ZabaqMUODUzV+YcjU1g7gChzawm2Y9GTfre9eeL4rW0VQPWGE6i6xd7ZF8yh82GMpFNJ1A3seS73mmM1+2MpJk7bAlg/8mFLaFHTeo/46+nH0yWg6KuhD4HCs1VcZO7GOEmayzpVh/nonRlCEFSM28NCZHY4F2DO+dLXBdXK1j38sd6axiS/GvQU2IUWY3vQ7mzac=----ATTACHMENT:----MjY1NTczNzEwMDUyNjQxOSA4NDI1MTEzMzU3NjQxNTAxIDU0NTI2MTY1MzUwMzI0NjM=