-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
106 lines (91 loc) · 2.76 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const { chunk } = require('./chunk');
const { sleep, reflect } = require('./async');
const { identity, compose } = require('./combinators');
const promiseChainLog = [];
const recursivePromiseChunk = chunk => res => Promise.all([...res, ...chunk]);
const chainChunks = (promiseChain, index, chunks, promiseFlavor) => {
let runFn, runFnStr;
const tab = '\t';
if (promiseFlavor === PromiseFlavor.PromiseAllSettled) {
runFn = compose(reflect)(identity);
runFnStr = `f =>
${tab.repeat(2)}f()
${tab.repeat(3)}.then(value => ({ status: 'fulfilled', value }))
${tab.repeat(3)}.catch(reason => ({ status: "rejected", reason }))`;
} else {
runFn = identity;
runFnStr = `f => f()`;
}
if (index === 0) {
promiseChain = Promise.all(chunks[0].map(runFn));
promiseChainLog.push(
`Promise.all( [ ${chunks[0].join(', ')} ]
${tab.repeat(1)}.map(${runFnStr})
)`
);
} else {
promiseChain = promiseChain.then(res =>
recursivePromiseChunk(chunks[index].map(runFn))(res)
);
promiseChainLog.push(
`.then((res) => Promise.all( [ ...res, ...[ ${chunks[index].join(', ')} ]
${tab.repeat(1)}.map(${runFnStr})
]))`
);
}
return promiseChain;
};
const chainCallback = (promiseChain, index, chunks, callback) => {
if (callback) {
promiseChain = promiseChain.then(res => {
return callback(res.slice(-chunks[index].length), index, res).then(
() => res
);
});
promiseChainLog.push(
`.then((res) => {
\t\treturn callback(chunkResults, ${index}, allResults).then(() => res);
})`
);
}
return promiseChain;
};
const chainSleep = (promiseChain, sleepMs) => {
if (sleepMs !== undefined) {
promiseChain = promiseChain.then(sleep(sleepMs));
promiseChainLog.push(
`.then((res) => new Promise(resolve => setTimeout(() => resolve(res), ${sleepMs})))`
);
}
return promiseChain;
};
const PromiseFlavor = {
PromiseAll: 'PromiseAll',
PromiseAllSettled: 'PromiseAllSettled'
};
const chunkPromise = (
promiseArr,
{
concurrent = Infinity,
sleepMs,
callback,
promiseFlavor = PromiseFlavor.PromiseAll,
logMe = false
} = {}
) => {
const chunks = chunk(promiseArr, concurrent);
let promiseChain = Promise.resolve();
for (let index = 0; index <= chunks.length - 1; index++) {
promiseChain = chainChunks(promiseChain, index, chunks, promiseFlavor);
promiseChain = chainCallback(promiseChain, index, chunks, callback);
promiseChain = chainSleep(promiseChain, sleepMs);
}
logMe && console.log(promiseChainLog.join('\n'));
return promiseChain;
};
const ChunkPromiseCallbackForceStopError = class extends Error {};
exports = module.exports = {
chunkPromise,
PromiseFlavor,
ChunkPromiseCallbackForceStopError
};