1 | # Neo-Async
|
2 |
|
3 | <img src="https://raw.githubusercontent.com/wiki/suguru03/neo-async/images/neo_async_v2.png" width="230px" />
|
4 |
|
5 | [![npm](https://img.shields.io/npm/v/neo-async.svg)](https://www.npmjs.com/package/neo-async)
|
6 | [![Travis](https://img.shields.io/travis/suguru03/neo-async.svg)](https://travis-ci.org/suguru03/neo-async)
|
7 | [![Codecov](https://img.shields.io/codecov/c/github/suguru03/neo-async.svg)](https://codecov.io/github/suguru03/neo-async?branch=master)
|
8 | [![Dependency Status](https://gemnasium.com/suguru03/neo-async.svg)](https://gemnasium.com/suguru03/neo-async)
|
9 | [![npm](https://img.shields.io/npm/dm/neo-async.svg)](https://www.npmjs.com/package/neo-async)
|
10 |
|
11 | Neo-Async is thought to be used as a drop-in replacement for [Async](https://github.com/caolan/async), it almost fully covers its functionality and runs [faster](#benchmark).
|
12 |
|
13 | Benchmark is [here](#benchmark)!
|
14 |
|
15 | Bluebird's benchmark is [here](https://github.com/suguru03/bluebird/tree/aigle/benchmark)!
|
16 |
|
17 | ## Code Coverage
|
18 | ![coverage](https://raw.githubusercontent.com/wiki/suguru03/neo-async/images/coverage.png)
|
19 |
|
20 | ## Installation
|
21 |
|
22 | ### In a browser
|
23 | ```html
|
24 | <script src="async.min.js"></script>
|
25 | ```
|
26 |
|
27 | ### In an AMD loader
|
28 | ```js
|
29 | require(['async'], function(async) {});
|
30 | ```
|
31 |
|
32 | ### Promise and async/await
|
33 |
|
34 | I recommend to use [`Aigle`](https://github.com/suguru03/aigle).
|
35 |
|
36 | It is optimized for Promise handling and has almost the same functionality as `neo-async`.
|
37 |
|
38 | ### Node.js
|
39 |
|
40 | #### standard
|
41 |
|
42 | ```bash
|
43 | $ npm install neo-async
|
44 | ```
|
45 | ```js
|
46 | var async = require('neo-async');
|
47 | ```
|
48 |
|
49 | #### replacement
|
50 | ```bash
|
51 | $ npm install neo-async
|
52 | $ ln -s ./node_modules/neo-async ./node_modules/async
|
53 | ```
|
54 | ```js
|
55 | var async = require('async');
|
56 | ```
|
57 |
|
58 | ### Bower
|
59 |
|
60 | ```bash
|
61 | bower install neo-async
|
62 | ```
|
63 |
|
64 | ## Feature
|
65 |
|
66 | [JSDoc](http://suguru03.github.io/neo-async/doc/async.html)
|
67 |
|
68 | \* not in Async
|
69 |
|
70 | ### Collections
|
71 |
|
72 | - [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
|
73 | - [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
|
74 | - [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
|
75 | - [`forEach`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
|
76 | - [`forEachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
|
77 | - [`forEachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
|
78 | - [`eachOf`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
|
79 | - [`eachOfSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
|
80 | - [`eachOfLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`eachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
|
81 | - [`forEachOf`](http://suguru03.github.io/neo-async/doc/async.each.html) -> [`each`](http://suguru03.github.io/neo-async/doc/async.each.html)
|
82 | - [`forEachOfSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html) -> [`eachSeries`](http://suguru03.github.io/neo-async/doc/async.eachSeries.html)
|
83 | - [`eachOfLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html) -> [`forEachLimit`](http://suguru03.github.io/neo-async/doc/async.eachLimit.html)
|
84 | - [`map`](http://suguru03.github.io/neo-async/doc/async.map.html)
|
85 | - [`mapSeries`](http://suguru03.github.io/neo-async/doc/async.mapSeries.html)
|
86 | - [`mapLimit`](http://suguru03.github.io/neo-async/doc/async.mapLimit.html)
|
87 | - [`mapValues`](http://suguru03.github.io/neo-async/doc/async.mapValues.html)
|
88 | - [`mapValuesSeries`](http://suguru03.github.io/neo-async/doc/async.mapValuesSeries.html)
|
89 | - [`mapValuesLimit`](http://suguru03.github.io/neo-async/doc/async.mapValuesLimit.html)
|
90 | - [`filter`](http://suguru03.github.io/neo-async/doc/async.filter.html)
|
91 | - [`filterSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html)
|
92 | - [`filterLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html)
|
93 | - [`select`](http://suguru03.github.io/neo-async/doc/async.filter.html) -> [`filter`](http://suguru03.github.io/neo-async/doc/async.filter.html)
|
94 | - [`selectSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html) -> [`filterSeries`](http://suguru03.github.io/neo-async/doc/async.filterSeries.html)
|
95 | - [`selectLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html) -> [`filterLimit`](http://suguru03.github.io/neo-async/doc/async.filterLimit.html)
|
96 | - [`reject`](http://suguru03.github.io/neo-async/doc/async.reject.html)
|
97 | - [`rejectSeries`](http://suguru03.github.io/neo-async/doc/async.rejectSeries.html)
|
98 | - [`rejectLimit`](http://suguru03.github.io/neo-async/doc/async.rejectLimit.html)
|
99 | - [`detect`](http://suguru03.github.io/neo-async/doc/async.detect.html)
|
100 | - [`detectSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html)
|
101 | - [`detectLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html)
|
102 | - [`find`](http://suguru03.github.io/neo-async/doc/async.detect.html) -> [`detect`](http://suguru03.github.io/neo-async/doc/async.detect.html)
|
103 | - [`findSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html) -> [`detectSeries`](http://suguru03.github.io/neo-async/doc/async.detectSeries.html)
|
104 | - [`findLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html) -> [`detectLimit`](http://suguru03.github.io/neo-async/doc/async.detectLimit.html)
|
105 | - [`pick`](http://suguru03.github.io/neo-async/doc/async.pick.html) *
|
106 | - [`pickSeries`](http://suguru03.github.io/neo-async/doc/async.pickSeries.html) *
|
107 | - [`pickLimit`](http://suguru03.github.io/neo-async/doc/async.pickLimit.html) *
|
108 | - [`omit`](http://suguru03.github.io/neo-async/doc/async.omit.html) *
|
109 | - [`omitSeries`](http://suguru03.github.io/neo-async/doc/async.omitSeries.html) *
|
110 | - [`omitLimit`](http://suguru03.github.io/neo-async/doc/async.omitLimit.html) *
|
111 | - [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html)
|
112 | - [`inject`](http://suguru03.github.io/neo-async/doc/async.reduce.html) -> [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html)
|
113 | - [`foldl`](http://suguru03.github.io/neo-async/doc/async.reduce.html) -> [`reduce`](http://suguru03.github.io/neo-async/doc/async.reduce.html)
|
114 | - [`reduceRight`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html)
|
115 | - [`foldr`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html) -> [`reduceRight`](http://suguru03.github.io/neo-async/doc/async.reduceRight.html)
|
116 | - [`transform`](http://suguru03.github.io/neo-async/doc/async.transform.html)
|
117 | - [`transformSeries`](http://suguru03.github.io/neo-async/doc/async.transformSeries.html) *
|
118 | - [`transformLimit`](http://suguru03.github.io/neo-async/doc/async.transformLimit.html) *
|
119 | - [`sortBy`](http://suguru03.github.io/neo-async/doc/async.sortBy.html)
|
120 | - [`sortBySeries`](http://suguru03.github.io/neo-async/doc/async.sortBySeries.html) *
|
121 | - [`sortByLimit`](http://suguru03.github.io/neo-async/doc/async.sortByLimit.html) *
|
122 | - [`some`](http://suguru03.github.io/neo-async/doc/async.some.html)
|
123 | - [`someSeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html)
|
124 | - [`someLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html)
|
125 | - [`any`](http://suguru03.github.io/neo-async/doc/async.some.html) -> [`some`](http://suguru03.github.io/neo-async/doc/async.some.html)
|
126 | - [`anySeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html) -> [`someSeries`](http://suguru03.github.io/neo-async/doc/async.someSeries.html)
|
127 | - [`anyLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html) -> [`someLimit`](http://suguru03.github.io/neo-async/doc/async.someLimit.html)
|
128 | - [`every`](http://suguru03.github.io/neo-async/doc/async.every.html)
|
129 | - [`everySeries`](http://suguru03.github.io/neo-async/doc/async.everySeries.html)
|
130 | - [`everyLimit`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html)
|
131 | - [`all`](http://suguru03.github.io/neo-async/doc/async.every.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.every.html)
|
132 | - [`allSeries`](http://suguru03.github.io/neo-async/doc/async.everySeries.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.everySeries.html)
|
133 | - [`allLimit`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html) -> [`every`](http://suguru03.github.io/neo-async/doc/async.everyLimit.html)
|
134 | - [`concat`](http://suguru03.github.io/neo-async/doc/async.concat.html)
|
135 | - [`concatSeries`](http://suguru03.github.io/neo-async/doc/async.concatSeries.html)
|
136 | - [`concatLimit`](http://suguru03.github.io/neo-async/doc/async.concatLimit.html) *
|
137 |
|
138 | ### Control Flow
|
139 |
|
140 | - [`parallel`](http://suguru03.github.io/neo-async/doc/async.parallel.html)
|
141 | - [`series`](http://suguru03.github.io/neo-async/doc/async.series.html)
|
142 | - [`parallelLimit`](http://suguru03.github.io/neo-async/doc/async.series.html)
|
143 | - [`tryEach`](http://suguru03.github.io/neo-async/doc/async.tryEach.html)
|
144 | - [`waterfall`](http://suguru03.github.io/neo-async/doc/async.waterfall.html)
|
145 | - [`angelFall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) *
|
146 | - [`angelfall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) -> [`angelFall`](http://suguru03.github.io/neo-async/doc/async.angelFall.html) *
|
147 | - [`whilst`](#whilst)
|
148 | - [`doWhilst`](#doWhilst)
|
149 | - [`until`](#until)
|
150 | - [`doUntil`](#doUntil)
|
151 | - [`during`](#during)
|
152 | - [`doDuring`](#doDuring)
|
153 | - [`forever`](#forever)
|
154 | - [`compose`](#compose)
|
155 | - [`seq`](#seq)
|
156 | - [`applyEach`](#applyEach)
|
157 | - [`applyEachSeries`](#applyEachSeries)
|
158 | - [`queue`](#queue)
|
159 | - [`priorityQueue`](#priorityQueue)
|
160 | - [`cargo`](#cargo)
|
161 | - [`auto`](#auto)
|
162 | - [`autoInject`](#autoInject)
|
163 | - [`retry`](#retry)
|
164 | - [`retryable`](#retryable)
|
165 | - [`iterator`](#iterator)
|
166 | - [`times`](http://suguru03.github.io/neo-async/doc/async.times.html)
|
167 | - [`timesSeries`](http://suguru03.github.io/neo-async/doc/async.timesSeries.html)
|
168 | - [`timesLimit`](http://suguru03.github.io/neo-async/doc/async.timesLimit.html)
|
169 | - [`race`](#race)
|
170 |
|
171 | ### Utils
|
172 | - [`apply`](#apply)
|
173 | - [`setImmediate`](#setImmediate)
|
174 | - [`nextTick`](#nextTick)
|
175 | - [`memoize`](#memoize)
|
176 | - [`unmemoize`](#unmemoize)
|
177 | - [`ensureAsync`](#ensureAsync)
|
178 | - [`constant`](#constant)
|
179 | - [`asyncify`](#asyncify)
|
180 | - [`wrapSync`](#asyncify) -> [`asyncify`](#asyncify)
|
181 | - [`log`](#log)
|
182 | - [`dir`](#dir)
|
183 | - [`timeout`](http://suguru03.github.io/neo-async/doc/async.timeout.html)
|
184 | - [`reflect`](#reflect)
|
185 | - [`reflectAll`](#reflectAll)
|
186 | - [`createLogger`](#createLogger)
|
187 |
|
188 | ## Mode
|
189 | - [`safe`](#safe) *
|
190 | - [`fast`](#fast) *
|
191 |
|
192 | ## Benchmark
|
193 |
|
194 | [Benchmark: Async vs Neo-Async](http://suguru03.hatenablog.com/entry/2016/06/10/135559)
|
195 |
|
196 | ### How to check
|
197 |
|
198 | ```bash
|
199 | $ git clone git@github.com:suguru03/async-benchmark.git
|
200 | $ cd async-benchmark
|
201 | $ npm install
|
202 | $ node . // It might take more than one hour...
|
203 | ```
|
204 |
|
205 | ### Environment
|
206 |
|
207 | * Ubuntu v12.04
|
208 | * Node.js v6.2.1
|
209 | * async v2.0.0-rc.6
|
210 | * neo-async v2.0.0-rc.1
|
211 | * benchmark v2.1.0
|
212 | * func-comparator v0.7.1
|
213 |
|
214 | ### Result
|
215 |
|
216 | Neo-Async is 1.27 ~ 10.7 times faster than Async.
|
217 |
|
218 | The value is the ratio (Neo-Async/Async) of the average speed.
|
219 |
|
220 | #### Collections
|
221 | |function|benchmark|func-comparator|
|
222 | |---|--:|--:|
|
223 | |each|3.71|2.54|
|
224 | |eachSeries|2.14|1.90|
|
225 | |eachLimit|2.14|1.88|
|
226 | |eachOf|3.30|2.50|
|
227 | |eachOfSeries|1.97|1.83|
|
228 | |eachOfLimit|2.02|1.80|
|
229 | |map|4.20|4.11|
|
230 | |mapSeries|2.40|3.65|
|
231 | |mapLimit|2.64|2.66|
|
232 | |mapValues|5.71|5.32|
|
233 | |mapValuesSeries|3.82|3.23|
|
234 | |mapValuesLimit|3.10|2.38|
|
235 | |filter|8.11|8.76|
|
236 | |filterSeries|5.79|4.86|
|
237 | |filterLimit|4.00|3.32|
|
238 | |reject|9.47|9.52|
|
239 | |rejectSeries|7.39|4.64|
|
240 | |rejectLimit|4.54|3.49|
|
241 | |detect|6.67|6.37|
|
242 | |detectSeries|3.54|3.73|
|
243 | |detectLimit|2.38|2.62|
|
244 | |reduce|4.13|3.23|
|
245 | |reduceRight|4.23|3.24|
|
246 | |transform|5.30|5.17|
|
247 | |sortBy|2.24|2.37|
|
248 | |some|6.39|6.10|
|
249 | |someSeries|5.37|4.66|
|
250 | |someLimit|3.39|2.84|
|
251 | |every|6.85|6.27|
|
252 | |everySeries|4.53|3.90|
|
253 | |everyLimit|3.36|2.75|
|
254 | |concat|9.18|9.35|
|
255 | |concatSeries|7.49|6.09|
|
256 |
|
257 | #### Control Flow
|
258 | |funciton|benchmark|func-comparator|
|
259 | |---|--:|--:|
|
260 | |parallel|7.54|5.45|
|
261 | |series|3.29|2.41|
|
262 | |waterfall|5.12|4.27|
|
263 | |whilst|1.96|1.95|
|
264 | |doWhilst|2.07|1.96|
|
265 | |until|2.10|1.99|
|
266 | |doUntil|1.98|2.04|
|
267 | |during|10.7|7.09|
|
268 | |doDuring|5.98|6.03|
|
269 | |queue|1.83|1.75|
|
270 | |priorityQueue|1.79|1.75|
|
271 | |times|3.84|3.65|
|
272 | |race|1.45|1.27|
|
273 | |auto|3.23|3.50|
|
274 | |retry|9.43|6.78|
|
275 |
|