diff --git a/README.md b/README.md index 77a0774..8fbe641 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,9 @@ whatsoever!* **Table of Contents** * [Usage](#usage) - * [Parallel](#parallel) - * [Waterfall](#waterfall) + * [parallel()](#parallel) + * [series()](#series) + * [waterfall()](#waterfall) * [Todo](#todo) * [Install](#install) * [Tests](#tests) @@ -34,15 +35,42 @@ whatsoever!* ## Usage -### Parallel +This lightweight library consists only of a few simple functions. +All functions reside under the `React\Async` namespace. + +The below examples refer to all functions with their fully-qualified names like this: + +```php +React\Async\parallel(…); +``` + +As of PHP 5.6+ you can also import each required function into your code like this: + +```php +use function React\Async\parallel; + +parallel(…); +``` + +Alternatively, you can also use an import statement similar to this: + +```php +use React\Async; + +Async\parallel(…); +``` + +### parallel() + +The `parallel(array $tasks, ?callable $callback = null, ?callable $errback = null): void` function can be used +like this: ```php $tasks, ?callable $callback = null, ?callable $errback = null): void` function can be used +like this: + +```php + $tasks, ?callable $callback = null, ?callable $errback = null): void` function can be used +like this: ```php $task) { - $taskCallback = function ($result) use (&$results, $i, $checkDone) { - $results[$i] = $result; - $checkDone(); - }; - - call_user_func($task, $taskCallback, $taskErrback); - } - } - - public static function waterfall($tasks, $callback = null, $errback = null) - { - $taskCallback = function () use (&$next) { - call_user_func_array($next, func_get_args()); - }; - - $done = function () use ($callback) { - if ($callback) { - call_user_func_array($callback, func_get_args()); - } - }; - - $next = function () use (&$tasks, $taskCallback, $errback, $done) { - if (0 === count($tasks)) { - call_user_func_array($done, func_get_args()); - return; - } - - $task = array_shift($tasks); - $args = array_merge(func_get_args(), array($taskCallback, $errback)); - call_user_func_array($task, $args); - }; - - $next(); - } -} diff --git a/src/functions.php b/src/functions.php new file mode 100644 index 0000000..b717cd8 --- /dev/null +++ b/src/functions.php @@ -0,0 +1,122 @@ + $tasks + * @param ?callable $callback + * @param ?callable $errback + * @return void + */ +function parallel(array $tasks, $callback = null, $errback = null) +{ + $results = array(); + $errors = array(); + + $done = function () use (&$results, &$errors, $callback, $errback) { + if (!$callback) { + return; + } + + if (count($errors)) { + $errback(array_shift($errors)); + return; + } + + $callback($results); + }; + + $numTasks = count($tasks); + + if (0 === $numTasks) { + $done(); + return; + } + + $checkDone = function () use (&$results, &$errors, $numTasks, $done) { + if ($numTasks === count($results) + count($errors)) { + $done(); + } + }; + + $taskErrback = function ($error) use (&$errors, $checkDone) { + $errors[] = $error; + $checkDone(); + }; + + foreach ($tasks as $i => $task) { + $taskCallback = function ($result) use (&$results, $i, $checkDone) { + $results[$i] = $result; + $checkDone(); + }; + + call_user_func($task, $taskCallback, $taskErrback); + } +} + +/** + * @param array $tasks + * @param ?callable $callback + * @param ?callable $errback + * @return void + */ +function series(array $tasks, $callback = null, $errback = null) +{ + $results = array(); + + /** @var callable():void $next */ + $taskCallback = function ($result) use (&$results, &$next) { + $results[] = $result; + $next(); + }; + + $done = function () use (&$results, $callback) { + if ($callback) { + call_user_func($callback, $results); + } + }; + + $next = function () use (&$tasks, $taskCallback, $errback, $done) { + if (0 === count($tasks)) { + $done(); + return; + } + + $task = array_shift($tasks); + call_user_func($task, $taskCallback, $errback); + }; + + $next(); +} + +/** + * @param array $tasks + * @param ?callable $callback + * @param ?callable $errback + * @return void + */ +function waterfall(array $tasks, $callback = null, $errback = null) +{ + $taskCallback = function () use (&$next) { + call_user_func_array($next, func_get_args()); + }; + + $done = function () use ($callback) { + if ($callback) { + call_user_func_array($callback, func_get_args()); + } + }; + + $next = function () use (&$tasks, $taskCallback, $errback, $done) { + if (0 === count($tasks)) { + call_user_func_array($done, func_get_args()); + return; + } + + $task = array_shift($tasks); + $args = array_merge(func_get_args(), array($taskCallback, $errback)); + call_user_func_array($task, $args); + }; + + $next(); +} diff --git a/src/functions_include.php b/src/functions_include.php new file mode 100644 index 0000000..92a7439 --- /dev/null +++ b/src/functions_include.php @@ -0,0 +1,8 @@ +expectCallableOnceWith(array()); $errback = $this->expectCallableNever(); - Util::parallel($tasks, $callback, $errback); + React\Async\parallel($tasks, $callback, $errback); } public function testParallelWithTasks() @@ -35,7 +35,7 @@ function ($callback, $errback) { $callback = $this->expectCallableOnceWith(array('foo', 'bar')); $errback = $this->expectCallableNever(); - Util::parallel($tasks, $callback, $errback); + React\Async\parallel($tasks, $callback, $errback); $timer = new Timer($this); $timer->start(); @@ -68,7 +68,7 @@ function ($callback, $errback) use (&$called) { $callback = $this->expectCallableNever(); $errback = $this->expectCallableOnce(); - Util::parallel($tasks, $callback, $errback); + React\Async\parallel($tasks, $callback, $errback); $this->assertSame(2, $called); } @@ -97,7 +97,7 @@ function ($callback, $errback) use (&$called) { $callback = $this->expectCallableNever(); $errback = $this->expectCallableOnce(); - Util::parallel($tasks, $callback, $errback); + React\Async\parallel($tasks, $callback, $errback); Loop::run(); diff --git a/tests/UtilSeriesTest.php b/tests/SeriesTest.php similarity index 88% rename from tests/UtilSeriesTest.php rename to tests/SeriesTest.php index 95fa182..7a6bb1b 100644 --- a/tests/UtilSeriesTest.php +++ b/tests/SeriesTest.php @@ -2,10 +2,10 @@ namespace React\Tests\Async; -use React\Async\Util; +use React; use React\EventLoop\Loop; -class UtilSeriesTest extends TestCase +class SeriesTest extends TestCase { public function testSeriesWithoutTasks() { @@ -14,7 +14,7 @@ public function testSeriesWithoutTasks() $callback = $this->expectCallableOnceWith(array()); $errback = $this->expectCallableNever(); - Util::series($tasks, $callback, $errback); + React\Async\series($tasks, $callback, $errback); } public function testSeriesWithTasks() @@ -35,7 +35,7 @@ function ($callback, $errback) { $callback = $this->expectCallableOnceWith(array('foo', 'bar')); $errback = $this->expectCallableNever(); - Util::series($tasks, $callback, $errback); + React\Async\series($tasks, $callback, $errback); $timer = new Timer($this); $timer->start(); @@ -68,7 +68,7 @@ function ($callback, $errback) use (&$called) { $callback = $this->expectCallableNever(); $errback = $this->expectCallableOnce(); - Util::series($tasks, $callback, $errback); + React\Async\series($tasks, $callback, $errback); $this->assertSame(1, $called); } diff --git a/tests/UtilWaterfallTest.php b/tests/WaterfallTest.php similarity index 89% rename from tests/UtilWaterfallTest.php rename to tests/WaterfallTest.php index b8d384b..c8711f8 100644 --- a/tests/UtilWaterfallTest.php +++ b/tests/WaterfallTest.php @@ -2,10 +2,10 @@ namespace React\Tests\Async; -use React\Async\Util; +use React; use React\EventLoop\Loop; -class UtilWaterfallTest extends TestCase +class WaterfallTest extends TestCase { public function testWaterfallWithoutTasks() { @@ -14,7 +14,7 @@ public function testWaterfallWithoutTasks() $callback = $this->expectCallableOnce(); $errback = $this->expectCallableNever(); - Util::waterfall($tasks, $callback, $errback); + React\Async\waterfall($tasks, $callback, $errback); } public function testWaterfallWithTasks() @@ -40,7 +40,7 @@ function ($bar, $callback, $errback) { $callback = $this->expectCallableOnceWith('foobarbaz'); $errback = $this->expectCallableNever(); - Util::waterfall($tasks, $callback, $errback); + React\Async\waterfall($tasks, $callback, $errback); $timer = new Timer($this); $timer->start(); @@ -73,7 +73,7 @@ function ($callback, $errback) use (&$called) { $callback = $this->expectCallableNever(); $errback = $this->expectCallableOnce(); - Util::waterfall($tasks, $callback, $errback); + React\Async\waterfall($tasks, $callback, $errback); $this->assertSame(1, $called); }