@@ -38,6 +38,7 @@ much any API that already uses Promises.
3838 * [ Promises] ( #promises )
3939 * [ Cancellation] ( #cancellation )
4040 * [ Timeout] ( #timeout )
41+ * [ all()] ( #all )
4142 * [ Blocking] ( #blocking )
4243* [ Install] ( #install )
4344* [ Tests] ( #tests )
@@ -256,6 +257,81 @@ $promise = Timer\timeout($q($url), 2.0, $loop);
256257Please refer to [ react/promise-timer] ( https://github.com/reactphp/promise-timer )
257258for more details.
258259
260+ #### all()
261+
262+ The static ` all(int $concurrency, array $jobs, callable $handler): PromiseInterface<mixed[]> ` method can be used to
263+ concurrently process all given jobs through the given ` $handler ` .
264+
265+ This is a convenience method which uses the ` Queue ` internally to
266+ schedule all jobs while limiting concurrency to ensure no more than
267+ ` $concurrency ` jobs ever run at once. It will return a promise which
268+ resolves with the results of all jobs on success.
269+
270+ ``` php
271+ $loop = React\EventLoop\Factory::create();
272+ $browser = new Clue\React\Buzz\Browser($loop);
273+
274+ $promise = Queue:all(3, $urls, function ($url) use ($browser) {
275+ return $browser->get($url);
276+ });
277+
278+ $promise->then(function (array $responses) {
279+ echo 'All ' . count($responses) . ' successful!' . PHP_EOL;
280+ });
281+ ```
282+
283+ If either of the jobs fail, it will reject the resulting promise and will
284+ try to cancel all outstanding jobs. Similarly, calling ` cancel() ` on the
285+ resulting promise will try to cancel all outstanding jobs. See
286+ [ promises] ( #promises ) and [ cancellation] ( #cancellation ) for details.
287+
288+ The ` $concurrency ` parameter sets a new soft limit for the maximum number
289+ of jobs to handle concurrently. Finding a good concurrency limit depends
290+ on your particular use case. It's common to limit concurrency to a rather
291+ small value, as doing more than a dozen of things at once may easily
292+ overwhelm the receiving side. Using a ` 1 ` value will ensure that all jobs
293+ are processed one after another, effectively creating a "waterfall" of
294+ jobs. Using a value less than 1 will reject with an
295+ ` InvalidArgumentException ` without processing any jobs.
296+
297+ ``` php
298+ // handle up to 10 jobs concurrently
299+ $promise = Queue:all(10, $jobs, $handler);
300+ ```
301+
302+ ``` php
303+ // handle each job after another without concurrency (waterfall)
304+ $promise = Queue:all(1, $jobs, $handler);
305+ ```
306+
307+ The ` $jobs ` parameter must be an array with all jobs to process. Each
308+ value in this array will be passed to the ` $handler ` to start one job.
309+ The array keys will be preserved in the resulting array, while the array
310+ values will be replaced with the job results as returned by the
311+ ` $handler ` . If this array is empty, this method will resolve with an
312+ empty array without processing any jobs.
313+
314+ The ` $handler ` parameter must be a valid callable that accepts your job
315+ parameters, invokes the appropriate operation and returns a Promise as a
316+ placeholder for its future result. If the given argument is not a valid
317+ callable, this method will reject with an ` InvalidArgumentExceptionn `
318+ without processing any jobs.
319+
320+ ``` php
321+ // using a Closure as handler is usually recommended
322+ $promise = Queue::all(10, $jobs, function ($url) use ($browser) {
323+ return $browser->get($url);
324+ });
325+ ```
326+
327+ ``` php
328+ // accepts any callable, so PHP's array notation is also supported
329+ $promise = Queue:all(10, $jobs, array($browser, 'get'));
330+ ```
331+
332+ > Keep in mind that returning an array of response messages means that
333+ the whole response body has to be kept in memory.
334+
259335#### Blocking
260336
261337As stated above, this library provides you a powerful, async API by default.
@@ -272,18 +348,12 @@ use Clue\React\Block;
272348$loop = React\EventLoop\Factory::create();
273349$browser = new Clue\React\Buzz\Browser($loop);
274350
275- $q = new Queue(10, null , function ($url) use ($browser) {
351+ $promise = Queue:all(3, $urls , function ($url) use ($browser) {
276352 return $browser->get($url);
277353});
278354
279- $promises = array(
280- $q('http://example.com/'),
281- $q('http://www.example.org/'),
282- $q('http://example.net/'),
283- );
284-
285355try {
286- $responses = Block\awaitAll($promises , $loop);
356+ $responses = Block\await($promise , $loop);
287357 // responses successfully received
288358} catch (Exception $e) {
289359 // an error occured while performing the requests
@@ -306,16 +376,11 @@ function download(array $uris)
306376 $loop = React\EventLoop\Factory::create();
307377 $browser = new Clue\React\Buzz\Browser($loop);
308378
309- $q = new Queue(10, null , function ($uri) use ($browser) {
379+ $promise = Queue::all(3, $uris , function ($uri) use ($browser) {
310380 return $browser->get($uri);
311381 });
312382
313- $promises = array();
314- foreach ($uris as $uri) {
315- $promises[$uri] = $q($uri);
316- }
317-
318- return Clue\React\Block\awaitAll($promises, $loop);
383+ return Clue\React\Block\await($promise, $loop);
319384}
320385```
321386
0 commit comments