@@ -5,31 +5,29 @@ const { asyncIter } = require('./async-iterator.js');
5
5
const { promisify } = require ( 'util' ) ;
6
6
7
7
// Asynchronous map (iterate parallel)
8
- // items - <Array >, incoming
8
+ // items - <Iterable >, incoming
9
9
// fn - <Function>, to be executed for each value in the array
10
10
// current - <any>, current element being processed in the array
11
11
// callback - <Function>
12
12
// err - <Error> | <null>
13
13
// value - <any>
14
14
// done - <Function>, on done, optional
15
15
// err - <Error> | <null>
16
- // result - <Array>
17
- const map = ( items , fn , done ) => {
18
- done = done || common . emptyness ;
16
+ // result - <Iterable>
17
+ const map = ( items , fn , done = common . emptyness ) => {
19
18
if ( ! items [ Symbol . iterator ] ) {
20
- done ( new TypeError ( 'items is not iterable' ) ) ;
19
+ done ( new TypeError ( '" items" argument is not iterable' ) ) ;
21
20
return ;
22
21
}
23
22
const isArray = Array . isArray ( items ) ;
24
- const data = asyncIter ( items ) . map ( item => promisify ( fn ) ( item ) ) ;
25
- const promise = isArray ? data . toArray ( ) : data . collectTo ( items . constructor ) ;
26
- promise . then ( res => done ( null , res ) , done ) ;
23
+ asyncIter ( items )
24
+ . parallel ( item => promisify ( fn ) ( item ) )
25
+ . then ( res => done ( null , isArray ? res : new items . constructor ( res ) ) )
26
+ . catch ( done ) ;
27
27
} ;
28
28
29
- const DEFAULT_OPTIONS = { min : 5 , percent : 0.7 } ;
30
-
31
29
// Non-blocking synchronous map
32
- // items - <Array >, incoming dataset
30
+ // items - <Iterable >, incoming dataset
33
31
// fn - <Function>
34
32
// item - <any>
35
33
// index - <number>
@@ -38,90 +36,53 @@ const DEFAULT_OPTIONS = { min: 5, percent: 0.7 };
38
36
// percent - <number>, ratio of map time to all time
39
37
// done - <Function>, call on done
40
38
// err - <Error> | <null>
41
- // result - <Array >
42
- const asyncMap = ( items , fn , options = { } , done ) => {
39
+ // result - <Iterable >
40
+ const asyncMap = ( items , fn , options = { } , done = common . emptyness ) => {
43
41
if ( typeof options === 'function' ) {
44
42
done = options ;
45
- options = DEFAULT_OPTIONS ;
43
+ options = { } ;
46
44
}
47
-
48
- const len = items . length || items . size ;
49
- const name = items . constructor . name ;
50
- let result = done ? new items . constructor ( ) : null ;
51
- const data = common . iter ( items ) ;
52
-
53
- if ( ! len || result === null ) {
54
- if ( done ) done ( null , result ) ;
45
+ if ( ! items [ Symbol . iterator ] ) {
46
+ done ( new TypeError ( '"items" argument is not iterable' ) ) ;
55
47
return ;
56
48
}
57
-
58
- const min = options . min || DEFAULT_OPTIONS . min ;
59
- const percent = options . percent || DEFAULT_OPTIONS . percent ;
60
-
61
- let begin ;
62
- let sum = 0 ;
63
- let count = 0 ;
64
-
65
- const ratio = percent / ( 1 - percent ) ;
66
-
67
- const countNumber = ( ) => {
68
- const loopTime = Date . now ( ) - begin ;
69
- const itemTime = sum / count ;
70
- const necessaryNumber = ( ratio * loopTime ) / itemTime ;
71
- return Math . max ( necessaryNumber , min ) ;
72
- } ;
73
-
74
- const next = ( ) => {
75
- const itemsNumber = count ? countNumber ( ) : min ;
76
- const iterMax = Math . min ( len , itemsNumber + count ) ;
77
-
78
- begin = Date . now ( ) ;
79
- for ( ; count < iterMax ; count ++ ) {
80
- const itemResult = fn ( data . next ( ) . value , count ) ;
81
- if ( done ) {
82
- if ( name === 'String' ) result += itemResult ;
83
- else if ( name === 'Array' ) result . push ( itemResult ) ;
84
- else if ( name === 'Set' ) result . add ( itemResult ) ;
85
- else result . set ( itemResult ) ;
86
- }
87
- }
88
- sum += Date . now ( ) - begin ;
89
-
90
- if ( count < len ) {
91
- begin = Date . now ( ) ;
92
- setTimeout ( next , 0 ) ;
93
- } else if ( done ) {
94
- done ( null , result ) ;
95
- }
96
- } ;
97
-
98
- next ( ) ;
49
+ const isArray = Array . isArray ( items ) ;
50
+ const iter = asyncIter ( items )
51
+ . map ( item => promisify ( fn ) ( item ) )
52
+ . throttle ( options . percent , options . min ) ;
53
+ const collect = isArray ? iter . toArray ( ) : iter . collectTo ( items . constructor ) ;
54
+ collect . then ( res => done ( null , res ) ) . catch ( done ) ;
99
55
} ;
100
56
101
57
// Asynchronous filter (iterate parallel)
102
- // items - <Array >, incoming
58
+ // items - <Iterable >, incoming
103
59
// fn - <Function>, to be executed for each value in the array
104
60
// value - <any>, item from items array
105
61
// callback - <Function>
106
62
// err - <Error> | <null>
107
63
// accepted - <boolean>
108
64
// done - <Function>, on done, optional
109
65
// err - <Error> | <null>
110
- // result - <Array>
111
- const filter = ( items , fn , done ) => {
112
- done = done || common . emptyness ;
66
+ // result - <Iterable>
67
+ const filter = ( items , fn , done = common . emptyness ) => {
113
68
if ( ! items [ Symbol . iterator ] ) {
114
- done ( new TypeError ( 'items is not iterable' ) ) ;
69
+ done ( new TypeError ( '" items" argument is not iterable' ) ) ;
115
70
return ;
116
71
}
117
72
const isArray = Array . isArray ( items ) ;
118
- const data = asyncIter ( items ) . filter ( item => promisify ( fn ) ( item ) ) ;
119
- const promise = isArray ? data . toArray ( ) : data . collectTo ( items . constructor ) ;
120
- promise . then ( res => done ( null , res ) , err => done ( err ) ) ;
73
+ asyncIter ( items )
74
+ . parallel ( async item => [ await promisify ( fn ) ( item ) , item ] )
75
+ . then ( res => {
76
+ const filtered = res
77
+ . filter ( ( [ predicateResult ] ) => predicateResult )
78
+ . map ( ( [ , item ] ) => item ) ;
79
+ done ( null , isArray ? filtered : new items . constructor ( filtered ) ) ;
80
+ } )
81
+ . catch ( done ) ;
121
82
} ;
122
83
123
84
// Asynchronous reduce
124
- // items - <Array >, incoming
85
+ // items - <Iterable >, incoming
125
86
// fn - <Function>, to be executed for each value in array
126
87
// previous - <any>, value previously returned in the last iteration
127
88
// current - <any>, current element being processed in the array
@@ -131,21 +92,21 @@ const filter = (items, fn, done) => {
131
92
// data - <any>, resulting value
132
93
// counter - <number>, index of the current element
133
94
// being processed in array
134
- // items - <Array >, the array reduce was called upon
95
+ // items - <Iterable >, the array reduce was called upon
135
96
// done - <Function>, on done, optional
136
97
// err - <Error> | <null>
137
- // result - <Array >
98
+ // result - <Iterable >
138
99
// initial - <any>, optional value to be used as first
139
100
// argument in first iteration
140
- const reduce = ( items , fn , done , initial ) => {
141
- done = done || common . emptyness ;
101
+ const reduce = ( items , fn , done = common . emptyness , initial ) => {
142
102
asyncIter ( items )
143
103
. reduce ( ( prev , cur ) => promisify ( fn ) ( prev , cur ) , initial )
144
- . then ( r => done ( null , r ) , done ) ;
104
+ . then ( res => done ( null , res ) )
105
+ . catch ( done ) ;
145
106
} ;
146
107
147
108
// Asynchronous reduceRight
148
- // items - <Array >, incoming
109
+ // items - <Iterable >, incoming
149
110
// fn - <Function>, to be executed for each value in array
150
111
// previous - <any>, value previously returned in the last iteration
151
112
// current - <any>, current element being processed in the array
@@ -155,53 +116,53 @@ const reduce = (items, fn, done, initial) => {
155
116
// data - <any>, resulting value
156
117
// counter - <number>, index of the current element
157
118
// being processed in array
158
- // items - <Array >, the array reduce was called upon
119
+ // items - <Iterable >, the array reduce was called upon
159
120
// done - <Function>, on done, optional
160
121
// err - <Error> | <null>
161
- // result - <Array >
122
+ // result - <Iterable >
162
123
// initial - <any>, optional value to be used as first
163
124
// argument in first iteration
164
- const reduceRight = ( items , fn , done , initial ) => {
165
- done = done || common . emptyness ;
125
+ const reduceRight = ( items , fn , done = common . emptyness , initial ) => {
166
126
asyncIter ( items )
167
127
. reduceRight ( ( prev , cur ) => promisify ( fn ) ( prev , cur ) , initial )
168
- . then ( r => done ( null , r ) , done ) ;
128
+ . then ( res => done ( null , res ) )
129
+ . catch ( done ) ;
169
130
} ;
170
131
171
132
// Asynchronous each (iterate in parallel)
172
- // items - <Array >, incoming
133
+ // items - <Iterable >, incoming
173
134
// fn - <Function>
174
135
// value - <any>, item from items array
175
136
// callback - <Function>
176
137
// err - <Error> | <null>
177
138
// done - <Function>, on done, optional
178
139
// err - <Error> | <null>
179
- // items - <Array>
180
- const each = ( items , fn , done ) => {
181
- done = done || common . emptyness ;
140
+ // items - <Iterable>
141
+ const each = ( items , fn , done = common . emptyness ) => {
182
142
asyncIter ( items )
183
143
. parallel ( item => promisify ( fn ) ( item ) )
184
- . then ( r => done ( null , r ) , done ) ;
144
+ . then ( res => done ( null , res ) )
145
+ . catch ( done ) ;
185
146
} ;
186
147
187
148
// Asynchronous series
188
- // items - <Array >, incoming
149
+ // items - <Iterable >, incoming
189
150
// fn - <Function>
190
151
// value - <any>, item from items array
191
152
// callback - <Function>
192
153
// err - <Error> | <null>
193
154
// done - <Function>, on done, optional
194
155
// err - <Error> | <null>
195
- // items - <Array>
196
- const series = ( items , fn , done ) => {
197
- done = done || common . emptyness ;
156
+ // items - <Iterable>
157
+ const series = ( items , fn , done = common . emptyness ) => {
198
158
asyncIter ( items )
199
159
. each ( item => promisify ( fn ) ( item ) )
200
- . then ( r => done ( null , r ) , done ) ;
160
+ . then ( res => done ( null , res ) )
161
+ . catch ( done ) ;
201
162
} ;
202
163
203
164
// Asynchronous find (iterate in series)
204
- // items - <Array >, incoming
165
+ // items - <Iterable >, incoming
205
166
// fn - <Function>,
206
167
// value - <any>, item from items array
207
168
// callback - <Function>
@@ -210,16 +171,15 @@ const series = (items, fn, done) => {
210
171
// done - <Function>, on done, optional
211
172
// err - <Error> | <null>
212
173
// result - <any>
213
- const find = ( items , fn , done ) => {
214
- done = done || common . emptyness ;
174
+ const find = ( items , fn , done = common . emptyness ) => {
215
175
asyncIter ( items )
216
176
. find ( item => promisify ( fn ) ( item ) )
217
- . then ( r => done ( null , r ) )
218
- . catch ( e => done ( e ) ) ;
177
+ . then ( res => done ( null , res ) )
178
+ . catch ( done ) ;
219
179
} ;
220
180
221
181
// Asynchronous every
222
- // items - <Array >, incoming
182
+ // items - <Iterable >, incoming
223
183
// fn - <Function>,
224
184
// value - <any>, item from items array
225
185
// callback - <Function>
@@ -228,16 +188,18 @@ const find = (items, fn, done) => {
228
188
// done - <Function>, on done, optional
229
189
// err - <Error> | <null>
230
190
// result - <boolean>
231
- const every = ( items , fn , done ) => {
232
- done = done || common . emptyness ;
191
+ const every = ( items , fn , done = common . emptyness ) => {
233
192
asyncIter ( items )
234
- . every ( item => promisify ( fn ) ( item ) )
235
- . then ( r => done ( null , r ) )
236
- . catch ( e => done ( e ) ) ;
193
+ . parallel ( item => promisify ( fn ) ( item ) )
194
+ . then ( res => {
195
+ const accepted = res . every ( predicateResult => predicateResult ) ;
196
+ done ( null , accepted ) ;
197
+ } )
198
+ . catch ( done ) ;
237
199
} ;
238
200
239
201
// Asynchronous some (iterate in series)
240
- // items - <Array >, incoming
202
+ // items - <Iterable >, incoming
241
203
// fn - <Function>
242
204
// value - <any>, item from items array
243
205
// callback - <Function>
@@ -246,12 +208,11 @@ const every = (items, fn, done) => {
246
208
// done - <Function>, on done
247
209
// err - <Error> | <null>
248
210
// result - <boolean>
249
- const some = ( items , fn , done ) => {
250
- done = done || common . emptyness ;
211
+ const some = ( items , fn , done = common . emptyness ) => {
251
212
asyncIter ( items )
252
213
. some ( item => promisify ( fn ) ( item ) )
253
- . then ( r => done ( null , r ) )
254
- . catch ( e => done ( e ) ) ;
214
+ . then ( res => done ( null , res ) )
215
+ . catch ( done ) ;
255
216
} ;
256
217
257
218
module . exports = {
0 commit comments