Skip to content

Commit e0a97b1

Browse files
authored
Merge pull request #6 from clue-labs/functions
Change to use functional API instead of static `Util` class
2 parents c89153a + a37c28e commit e0a97b1

8 files changed

+227
-132
lines changed

README.md

+78-9
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,52 @@ whatsoever!*
2525
**Table of Contents**
2626

2727
* [Usage](#usage)
28-
* [Parallel](#parallel)
29-
* [Waterfall](#waterfall)
28+
* [parallel()](#parallel)
29+
* [series()](#series)
30+
* [waterfall()](#waterfall)
3031
* [Todo](#todo)
3132
* [Install](#install)
3233
* [Tests](#tests)
3334
* [License](#license)
3435

3536
## Usage
3637

37-
### Parallel
38+
This lightweight library consists only of a few simple functions.
39+
All functions reside under the `React\Async` namespace.
40+
41+
The below examples refer to all functions with their fully-qualified names like this:
42+
43+
```php
44+
React\Async\parallel(…);
45+
```
46+
47+
As of PHP 5.6+ you can also import each required function into your code like this:
48+
49+
```php
50+
use function React\Async\parallel;
51+
52+
parallel(…);
53+
```
54+
55+
Alternatively, you can also use an import statement similar to this:
56+
57+
```php
58+
use React\Async;
59+
60+
Async\parallel(…);
61+
```
62+
63+
### parallel()
64+
65+
The `parallel(array<callable> $tasks, ?callable $callback = null, ?callable $errback = null): void` function can be used
66+
like this:
3867

3968
```php
4069
<?php
4170

42-
use React\Async\Util as Async;
4371
use React\EventLoop\Loop;
4472

45-
Async::parallel(
73+
React\Async\parallel(
4674
array(
4775
function ($callback, $errback) {
4876
Loop::addTimer(1, function () use ($callback) {
@@ -65,18 +93,59 @@ Async::parallel(
6593
var_dump($result);
6694
}
6795
},
68-
function (\Exception $e) {
96+
function (Exception $e) {
6997
throw $e;
7098
}
7199
);
72100
```
73101

74-
### Waterfall
102+
### series()
103+
104+
The `series(array<callable> $tasks, ?callable $callback = null, ?callable $errback = null): void` function can be used
105+
like this:
106+
107+
```php
108+
<?php
109+
110+
use React\EventLoop\Loop;
111+
112+
React\Async\series(
113+
array(
114+
function ($callback, $errback) {
115+
Loop::addTimer(1, function () use ($callback) {
116+
$callback('Slept for a whole second');
117+
});
118+
},
119+
function ($callback, $errback) {
120+
Loop::addTimer(1, function () use ($callback) {
121+
$callback('Slept for another whole second');
122+
});
123+
},
124+
function ($callback, $errback) {
125+
Loop::addTimer(1, function () use ($callback) {
126+
$callback('Slept for yet another whole second');
127+
});
128+
},
129+
),
130+
function (array $results) {
131+
foreach ($results as $result) {
132+
var_dump($result);
133+
}
134+
},
135+
function (Exception $e) {
136+
throw $e;
137+
}
138+
);
139+
```
140+
141+
### waterfall()
142+
143+
The `waterfall(array<callable> $tasks, ?callable $callback = null, ?callable $errback = null): void` function can be used
144+
like this:
75145

76146
```php
77147
<?php
78148

79-
use React\Async\Util as Async;
80149
use React\EventLoop\Loop;
81150

82151
$addOne = function ($prev, $callback = null) {
@@ -90,7 +159,7 @@ $addOne = function ($prev, $callback = null) {
90159
});
91160
};
92161

93-
Async::waterfall(array(
162+
React\Async\waterfall(array(
94163
$addOne,
95164
$addOne,
96165
$addOne,

composer.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@
3636
"react/event-loop": "You need an event loop for this to make sense."
3737
},
3838
"autoload": {
39-
"psr-4": { "React\\Async\\": "src/" }
39+
"files": [
40+
"src/functions_include.php"
41+
]
4042
},
4143
"autoload-dev": {
4244
"psr-4": { "React\\Tests\\Async\\": "tests/" }

src/Util.php

-106
This file was deleted.

src/functions.php

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
namespace React\Async;
4+
5+
/**
6+
* @param array<callable> $tasks
7+
* @param ?callable $callback
8+
* @param ?callable $errback
9+
* @return void
10+
*/
11+
function parallel(array $tasks, $callback = null, $errback = null)
12+
{
13+
$results = array();
14+
$errors = array();
15+
16+
$done = function () use (&$results, &$errors, $callback, $errback) {
17+
if (!$callback) {
18+
return;
19+
}
20+
21+
if (count($errors)) {
22+
$errback(array_shift($errors));
23+
return;
24+
}
25+
26+
$callback($results);
27+
};
28+
29+
$numTasks = count($tasks);
30+
31+
if (0 === $numTasks) {
32+
$done();
33+
return;
34+
}
35+
36+
$checkDone = function () use (&$results, &$errors, $numTasks, $done) {
37+
if ($numTasks === count($results) + count($errors)) {
38+
$done();
39+
}
40+
};
41+
42+
$taskErrback = function ($error) use (&$errors, $checkDone) {
43+
$errors[] = $error;
44+
$checkDone();
45+
};
46+
47+
foreach ($tasks as $i => $task) {
48+
$taskCallback = function ($result) use (&$results, $i, $checkDone) {
49+
$results[$i] = $result;
50+
$checkDone();
51+
};
52+
53+
call_user_func($task, $taskCallback, $taskErrback);
54+
}
55+
}
56+
57+
/**
58+
* @param array<callable> $tasks
59+
* @param ?callable $callback
60+
* @param ?callable $errback
61+
* @return void
62+
*/
63+
function series(array $tasks, $callback = null, $errback = null)
64+
{
65+
$results = array();
66+
67+
/** @var callable():void $next */
68+
$taskCallback = function ($result) use (&$results, &$next) {
69+
$results[] = $result;
70+
$next();
71+
};
72+
73+
$done = function () use (&$results, $callback) {
74+
if ($callback) {
75+
call_user_func($callback, $results);
76+
}
77+
};
78+
79+
$next = function () use (&$tasks, $taskCallback, $errback, $done) {
80+
if (0 === count($tasks)) {
81+
$done();
82+
return;
83+
}
84+
85+
$task = array_shift($tasks);
86+
call_user_func($task, $taskCallback, $errback);
87+
};
88+
89+
$next();
90+
}
91+
92+
/**
93+
* @param array<callable> $tasks
94+
* @param ?callable $callback
95+
* @param ?callable $errback
96+
* @return void
97+
*/
98+
function waterfall(array $tasks, $callback = null, $errback = null)
99+
{
100+
$taskCallback = function () use (&$next) {
101+
call_user_func_array($next, func_get_args());
102+
};
103+
104+
$done = function () use ($callback) {
105+
if ($callback) {
106+
call_user_func_array($callback, func_get_args());
107+
}
108+
};
109+
110+
$next = function () use (&$tasks, $taskCallback, $errback, $done) {
111+
if (0 === count($tasks)) {
112+
call_user_func_array($done, func_get_args());
113+
return;
114+
}
115+
116+
$task = array_shift($tasks);
117+
$args = array_merge(func_get_args(), array($taskCallback, $errback));
118+
call_user_func_array($task, $args);
119+
};
120+
121+
$next();
122+
}

src/functions_include.php

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace React\Async;
4+
5+
// @codeCoverageIgnoreStart
6+
if (!function_exists(__NAMESPACE__ . '\\parallel')) {
7+
require __DIR__ . '/functions.php';
8+
}

0 commit comments

Comments
 (0)