UNPKG

6.99 kBJavaScriptView Raw
1/**
2 * @copyright Copyright (c) 2019 Maxim Khorin <maksimovichu@gmail.com>
3 */
4'use strict';
5
6module.exports = class AsyncHelper {
7
8 // SERIES
9
10 static series (items, callback) {
11 const result = Array.isArray(items) ? [] : {};
12 if (!items) {
13 return callback(null, result);
14 }
15 const keys = Object.keys(items);
16 if (!keys.length) {
17 return callback(null, result);
18 }
19 (new this({items, callback, keys, result})).series();
20 }
21
22 static eachSeries (items, handler, callback) {
23 if (!Array.isArray(items) || !items.length) {
24 return callback();
25 }
26 (new this({items, handler, callback})).eachSeries();
27 }
28
29 static eachOfSeries (items, handler, callback) {
30 if (!items) {
31 return callback();
32 }
33 const keys = Object.keys(items);
34 if (!keys.length) {
35 return callback();
36 }
37 (new this({items, handler, callback, keys})).eachOfSeries();
38 }
39
40 static mapSeries (items, handler, callback) {
41 const result = [];
42 if (!Array.isArray(items) || !items.length) {
43 return callback(null, result);
44 }
45 (new this({items, handler, callback, result})).mapSeries();
46 }
47
48 static filterSeries (items, handler, callback) {
49 const result = [];
50 if (!Array.isArray(items) || !items.length) {
51 return callback(null, result);
52 }
53 (new this({items, handler, callback, result})).filterSeries();
54 }
55
56 static someSeries (items, handler, callback) {
57 if (!Array.isArray(items) || !items.length) {
58 return callback(null, false);
59 }
60 (new this({items, handler, callback})).someSeries();
61 }
62
63 static mapValuesSeries (items, handler, callback) {
64 const result = {};
65 if (!items) {
66 return callback(null, result);
67 }
68 const keys = Object.keys(items);
69 if (!keys.length) {
70 return callback(null, result);
71 }
72 (new this({items, handler, callback, keys, result})).mapValuesSeries();
73 }
74
75 static waterfall (items, callback) {
76 if (!Array.isArray(items) || !items.length) {
77 return callback();
78 }
79 (new this({items, callback})).waterfall();
80 }
81
82 // PARALLEL
83
84 static each (items, handler, callback) {
85 if (!Array.isArray(items) || !items.length) {
86 return callback();
87 }
88 (new this({items, handler, callback, counter: 0})).each();
89 }
90
91 static parallel (items, callback) {
92 const result = Array.isArray(items) ? [] : {};
93 if (!items) {
94 return callback(null, result);
95 }
96 const keys = Object.keys(items);
97 if (!keys.length) {
98 return callback(null, result);
99 }
100 (new this({items, callback, keys, result, counter: 0})).each();
101 }
102
103 // METHOD
104
105 constructor (config) {
106 Object.assign(this, config);
107 }
108
109 series (pos = 0) {
110 this.items[this.keys[pos]]((err, value) => {
111 if (err) {
112 return this.callback(err);
113 }
114 this.result[this.keys[pos]] = value;
115 if (++pos === this.keys.length) {
116 return this.callback(null, this.result);
117 }
118 this.series(pos);
119 });
120 }
121
122 eachSeries (pos = 0) {
123 this.handler(this.items[pos], err => {
124 if (err) {
125 return this.callback(err);
126 }
127 if (++pos === this.items.length) {
128 return this.callback();
129 }
130 this.eachSeries(pos);
131 });
132 }
133
134 eachOfSeries (pos = 0) {
135 this.handler(this.items[this.keys[pos]], this.keys[pos], err => {
136 if (err) {
137 return this.callback(err);
138 }
139 if (++pos === this.keys.length) {
140 return this.callback();
141 }
142 this.eachOfSeries(pos);
143 });
144 }
145
146 mapSeries (pos = 0) {
147 this.handler(this.items[pos], (err, value) => {
148 if (err) {
149 return this.callback(err);
150 }
151 this.result.push(value);
152 if (++pos === this.items.length) {
153 return this.callback(null, this.result);
154 }
155 this.mapSeries(pos);
156 });
157 }
158
159 filterSeries (pos = 0) {
160 this.handler(this.items[pos], (err, value) => {
161 if (err) {
162 return this.callback(err);
163 }
164 if (value) {
165 this.result.push(value);
166 }
167 if (++pos === this.items.length) {
168 return this.callback(null, this.result);
169 }
170 this.filterSeries(pos);
171 });
172 }
173
174 someSeries (pos = 0) {
175 this.handler(this.items[pos], (err, value) => {
176 if (err) {
177 return this.callback(err);
178 }
179 if (value) {
180 return this.callback(null, true);
181 }
182 if (++pos === this.items.length) {
183 return this.callback(null, false);
184 }
185 this.someSeries(pos);
186 });
187 }
188
189 mapValuesSeries (pos = 0) {
190 this.handler(this.items[this.keys[pos]], this.keys[pos], (err, value) => {
191 if (err) {
192 return this.callback(err);
193 }
194 this.result[this.keys[pos]] = value;
195 if (++pos === this.keys.length) {
196 return this.callback(null, this.result);
197 }
198 this.mapValuesSeries(pos);
199 });
200 }
201
202 waterfall (result = [], pos = 0) {
203 result.push((err, ...result) => {
204 if (err) {
205 return this.callback(err);
206 }
207 if (++pos === this.items.length) {
208 result.unshift(null);
209 return this.callback(...result);
210 }
211 this.waterfall(result, pos);
212 });
213 this.items[pos](...result);
214 }
215
216 // PARALLEL
217
218 each () {
219 const process = err => {
220 if (err || ++this.counter === this.items.length) {
221 this.callback(err);
222 }
223 };
224 for (const item of this.items) {
225 this.handler(item, process);
226 }
227 }
228
229 parallel () {
230 for (const key of this.keys) {
231 this.items[key](this.processParallel.bind(this, key));
232 }
233 }
234
235 processParallel (key, err, value) {
236 if (err) {
237 return this.callback(err);
238 }
239 this.result[key] = value;
240 if (++this.counter === this.keys.length) {
241 this.callback(null, this.result);
242 }
243 }
244};
\No newline at end of file