1 | # Async
|
2 |
|
3 | Control flow ala ES7 async/await with async.js (v2) signatures
|
4 |
|
5 | ------
|
6 |
|
7 | ## Table of Contents
|
8 |
|
9 | * [Motivation](#Motivation)
|
10 | * [API](#API)
|
11 | * [eachLimit()](#eachLimit)
|
12 | * [eachOfLimit()](#eachOfLimit)
|
13 | * [each()](#each)
|
14 | * [eachOf()](#eachOf)
|
15 | * [eachSeries()](#eachSeries)
|
16 | * [eachOfSeries()](#eachOfSeries)
|
17 | * [retryUntil()](#retryUntil)
|
18 | * [sleep()](#sleep)
|
19 | * [timeout()](#timeout)
|
20 | * [setImmediate()](#setImmediate)
|
21 | * [queue()](#queue)
|
22 | * [throttle()](#throttle)
|
23 | * [Tests](#Tests)
|
24 | * [TODO](#TODO)
|
25 | * [Credits](#Credits)
|
26 | * [Alternatives / relatives](#Alternatives)
|
27 | * [Shoutbox, keywords, SEO love](#keywords)
|
28 |
|
29 | ------
|
30 |
|
31 | <a name="Motivation"></a>
|
32 | # Motivation
|
33 |
|
34 | [nyks/async](./async/) provide javascript async/await equivalent signatures of the excellent [async](https://github.com/caolan/async) workflow library.
|
35 |
|
36 | Module are exported in standard commonJS module format and written in strict format. (no transpilation required nor used).
|
37 | Use browserify if you need nyks/async modules in a browser environnement.
|
38 |
|
39 | **nyks/async** is not a wrapper on **async**, but rather leverages the full potential of native async/await & promises contract. Code tend to be small & very efficient (far more simplier than using callbacks), just give [nyks/async/queue.js](./async/queue.js) a look.
|
40 |
|
41 |
|
42 | ## Addition to the async library signatures / promise pooling
|
43 |
|
44 | * Async functions cannot use arrow function binding style, yet it might be usefull to bind nyks/async closure, therefore, you can use an extra optional args to all signature to set async function binding context. (i.e. as in native [.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) )
|
45 | * Per design, it's easy to "throttle" a function that return a Promise ; checkout the "throttle" API for a way to make an ultra simple http request pooling.
|
46 | * async logic allow async/each to iterate through array AND objects. Per design sanify, nyks/async does not. Use each/eachLimit/eachSeries for arrays, eachOf/eachOfLimit/eachOfSeries for collections.
|
47 |
|
48 | ------
|
49 |
|
50 | <a name="API"></a>
|
51 | # API
|
52 |
|
53 | <a name="eachLimit"></a>
|
54 | ## eachLimit(arr, concurrency, thunk [, thisobj]) : Promise
|
55 |
|
56 | Applies the function 'thunk' to each item in 'arr', in parallel, with a limit async operations of 'concurrency' at a time. The 'thunk' is called with an item from the Array 'arr'.
|
57 |
|
58 | ```javascript
|
59 | const eachLimit = require('nyks/async/eachLimit');
|
60 |
|
61 | (async function() {
|
62 |
|
63 | var stuffs = [1, 2, 3, 5, 6];
|
64 |
|
65 | await eachLimit(stuffs, 2, async function(id) {
|
66 | await dootherStuffs(id);
|
67 | });
|
68 |
|
69 | })();
|
70 | ```
|
71 |
|
72 | ------
|
73 |
|
74 | <a name="eachOfLimit"></a>
|
75 | ## eachOfLimit(dict, concurrency, thunk [, thisobj]) : Promise
|
76 |
|
77 | Applies the function 'thunk' to each item of 'dict', in parallel, with a limit async operations of 'concurrency' at a time. The 'thunk' is called with an item from the Object 'dict'.
|
78 |
|
79 | ```javascript
|
80 | const eachOfLimit = require('nyks/async/eachOfLimit');
|
81 |
|
82 | (async function() {
|
83 |
|
84 | var stuffs = {
|
85 | 'number' : 1,
|
86 | 'number' : 2,
|
87 | 'number' : 3,
|
88 | 'number' : 4
|
89 | };
|
90 |
|
91 | await eachOfLimit(stuffs, 2, async function(id, key) {
|
92 | await dootherStuffs(id);
|
93 | });
|
94 |
|
95 | })();
|
96 | ```
|
97 |
|
98 | ------
|
99 |
|
100 | <a name="each"></a>
|
101 | ## each(arr, thunk [, thisobj]) : Promise
|
102 |
|
103 | Like eachLimit with a concurrency of arr.length.
|
104 |
|
105 | ```javascript
|
106 | const each = require('nyks/async/each');
|
107 |
|
108 | (async function() {
|
109 |
|
110 | var stuffs = [1, 2, 3, 5, 6];
|
111 |
|
112 | await each(stuffs, async function(id) {
|
113 | await dootherStuffs(id);
|
114 | });
|
115 |
|
116 | })();
|
117 | ```
|
118 |
|
119 | ------
|
120 |
|
121 | <a name="eachOf"></a>
|
122 | ## eachOf(dict, thunk [, thisobj]) : Promise
|
123 |
|
124 | Like eachOfLimit with a concurrency of dict.length.
|
125 |
|
126 | ```javascript
|
127 | const eachOf = require('nyks/async/eachOf');
|
128 |
|
129 | (async function() {
|
130 |
|
131 | var stuffs = {
|
132 | 'number' : 1,
|
133 | 'number' : 2,
|
134 | 'number' : 3,
|
135 | 'number' : 4
|
136 | };
|
137 |
|
138 | await eachOf(stuffs, async function(id, key) {
|
139 | await dootherStuffs(id);
|
140 | });
|
141 |
|
142 | })();
|
143 | ```
|
144 |
|
145 | ------
|
146 |
|
147 | <a name="eachSeries"></a>
|
148 | ## eachSeries(arr, thunk [, thisobj]) : Function
|
149 |
|
150 | Like eachLimit with a concurrency of 1.
|
151 |
|
152 | ```javascript
|
153 | const eachSeries = require('nyks/async/eachSeries');
|
154 |
|
155 | (async function() {
|
156 |
|
157 | var stuffs = [1, 2, 3, 5, 6];
|
158 |
|
159 | await eachSeries(stuffs, async function(id) {
|
160 | await dootherStuffs(id);
|
161 | });
|
162 |
|
163 | })();
|
164 | ```
|
165 |
|
166 | ------
|
167 |
|
168 | <a name="eachOfSeries"></a>
|
169 | ## eachOfSeries(dict, thunk [, thisobj]) : Function
|
170 |
|
171 | Like eachOfLimit with a concurrency of 1.
|
172 |
|
173 | ```javascript
|
174 | const eachOfSeries = require('nyks/async/eachOfSeries');
|
175 |
|
176 | (async function() {
|
177 |
|
178 | var stuffs = {
|
179 | 'number' : 1,
|
180 | 'number' : 2,
|
181 | 'number' : 3,
|
182 | 'number' : 4
|
183 | };
|
184 |
|
185 | await eachOfSeries(stuffs, async function(id, key) {
|
186 | await dootherStuffs(id);
|
187 | });
|
188 |
|
189 | })();
|
190 | ```
|
191 |
|
192 | ------
|
193 |
|
194 | <a name="retryUntil"></a>
|
195 | ## retryUntil(thunk, timeout, delay, [, failure]) : Function
|
196 |
|
197 | Run thunk until it resolves a truthy value, until timeout is reached. Wait **delay** between each attempt. On timeout, reject with a generic "Timeout" error message (or the specified failure, if any).
|
198 |
|
199 | ```javascript
|
200 | const retryUntil = require('nyks/async/retryUntil');
|
201 |
|
202 | (async function() {
|
203 |
|
204 | await tryUntil(async () => {
|
205 | return net.connect(...)
|
206 | }, 60 * 1000, 1000, 'Could not connect to remote socket');
|
207 |
|
208 | })();
|
209 | ```
|
210 |
|
211 |
|
212 |
|
213 |
|
214 | <a name="sleep"></a>
|
215 | ## sleep(delay) : Promise
|
216 |
|
217 | setTimeout as a promise.
|
218 |
|
219 | ```javascript
|
220 | const sleep = require('nyks/async/sleep');
|
221 |
|
222 | (async function() {
|
223 |
|
224 | // this is now
|
225 | await sleep(2000);
|
226 | // this is now + 2 secondes
|
227 |
|
228 | })();
|
229 | ```
|
230 |
|
231 | ------
|
232 |
|
233 | <a name="timeout"></a>
|
234 | ## timeout(delay, [, reason]) : Promise
|
235 |
|
236 | return a Promise that reject after delay (with reason = 'timeout')
|
237 |
|
238 | ```javascript
|
239 | const timeout = require('nyks/async/timeout');
|
240 |
|
241 | (async function() {
|
242 | await timeout(1000); // this will throw with message 'timeout'
|
243 | })();
|
244 | ```
|
245 |
|
246 | ------
|
247 |
|
248 | <a name="setImmediate"></a>
|
249 | ## setImmediate(fn) : Function
|
250 |
|
251 | Call a function in javascript next tick (using setImmediate API, or timeout 0 pollyfill)
|
252 |
|
253 | ```javascript
|
254 | const setImmediate = require('nyks/async/setImmediate');
|
255 |
|
256 | (async function() {
|
257 |
|
258 | // this is now
|
259 | await setImmediate();
|
260 | // this is still now...
|
261 |
|
262 | })();
|
263 | ```
|
264 |
|
265 | ------
|
266 |
|
267 | <a name="queue"></a>
|
268 | ## queue(thunk, concurrency) : Object
|
269 |
|
270 | Return a QueueObject you can push task into.
|
271 | Wait for thunk to process task (wait for worker, if needed).
|
272 |
|
273 | ```javascript
|
274 | const fetch = require('node-fetch');
|
275 | const queue = require('nyks/async/queue');
|
276 |
|
277 | var q = queue(fetch, 1); //let's be nice
|
278 |
|
279 | (async function() {
|
280 | await q.push("http://example.com/stuff.json");
|
281 | })();
|
282 |
|
283 | (async function() {
|
284 | await q.push("http://example.com/otherstuff.json"); //will wait for stuff to be retrieved
|
285 | })();
|
286 | ```
|
287 |
|
288 | ------
|
289 |
|
290 | <a name="throttle"></a>
|
291 | ## throttle(thunk, concurrency) : Function
|
292 |
|
293 | Throttle any function that return a promise, sugar syntax helper for nyks/async/queue.
|
294 |
|
295 | ```javascript
|
296 | const fetch = require('node-fetch');
|
297 | const throttle = require('nyks/async/throttle');
|
298 |
|
299 | fetch = throttle(fetch, 1); //make fetch behave nicely
|
300 |
|
301 | (async function() {
|
302 | await fetch("http://example.com/stuff.json");
|
303 | })();
|
304 |
|
305 | (async function() {
|
306 | await fetch("http://example.com/otherstuff.json"); //will wait for stuff.json to be retrieved
|
307 | })();
|
308 | ```
|
309 |
|
310 | ------
|
311 |
|
312 | <a name="Tests"></a>
|
313 | # Tests
|
314 | nyks/async is tested against async test suite (of course)
|
315 |
|
316 | ------
|
317 |
|
318 | <a nam="TODO"></a>
|
319 | # TODO
|
320 | * Get rich or die tryin'
|
321 | * write a working nyks/async/cargo (see [the challenge on stackoverflow](http://stackoverflow.com/questions/39069624))
|
322 |
|
323 | ------
|
324 |
|
325 | <a name="Credits"></a>
|
326 | # Credits
|
327 | * [131](https://github.com/131)
|
328 | * inspired from the excellent [async](https://github.com/caolan/async)
|
329 | * Derived from [async-co](https://github.com/131/async-co)
|
330 |
|
331 | ------
|
332 |
|
333 | <a name="Alternatives"></a>
|
334 | # Alternatives / relatives
|
335 | * [koa-async](https://github.com/eladnava/koa-async); a clever Promisify wrapper on top of async (but not leveraging the full potential of ES7 async/await capabilities)
|
336 | * [caolan/async/asyncify.js](https://github.com/caolan/async/blob/master/lib/asyncify.js); goes the same as koa-async.
|
337 | * [es6-promise-pool](https://github.com/timdp/es6-promise-pool); equivalent to nyks/async/queue, with a different API
|
338 |
|
339 | ------
|
340 |
|
341 | <a name="keywords"></a>
|
342 | # Shoutbox, keywords, SEO love
|
343 | async/await, co, nyks/async, promise, Promises, yield, async, queue, map, throttle, "Let's have a beer & talk in Paris"
|