2022-12-08 17:17:11 +01:00
|
|
|
'use strict';
|
|
|
|
|
2022-12-20 12:00:49 +01:00
|
|
|
const { chunk } = require('lodash/fp');
|
|
|
|
|
2022-12-08 17:17:11 +01:00
|
|
|
function pipeAsync(...methods) {
|
|
|
|
return async (data) => {
|
|
|
|
let res = data;
|
|
|
|
|
|
|
|
for (const method of methods) {
|
|
|
|
res = await method(res);
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-12-19 17:24:12 +01:00
|
|
|
* @type { import('./async').mapAsync }
|
2022-12-08 17:17:11 +01:00
|
|
|
*/
|
2022-12-20 12:00:49 +01:00
|
|
|
function mapAsync(promiseArray, { concurrency = Infinity } = {}) {
|
|
|
|
const appliedConcurrency = concurrency > promiseArray.length ? promiseArray.length : concurrency;
|
|
|
|
const promiseArrayChunks = chunk(appliedConcurrency)(promiseArray);
|
|
|
|
|
|
|
|
return async (callback) => {
|
|
|
|
return promiseArrayChunks.reduce(async (prevChunksPromise, chunk, chunkIndex) => {
|
|
|
|
// Need to await previous promise in order to respect the concurrency option
|
|
|
|
const prevChunks = await prevChunksPromise;
|
|
|
|
// As chunks can contain promises, we need to await the chunk
|
|
|
|
const awaitedChunk = await Promise.all(chunk);
|
|
|
|
const transformedPromiseChunk = await Promise.all(
|
|
|
|
// Calculating the index based on the original array, we do not want to have the index of the element inside the chunk
|
|
|
|
awaitedChunk.map((value, index) => callback(value, chunkIndex * appliedConcurrency + index))
|
|
|
|
);
|
|
|
|
|
|
|
|
return prevChunks.concat(transformedPromiseChunk);
|
|
|
|
}, Promise.resolve([]));
|
2022-12-08 17:17:11 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-12-19 17:24:12 +01:00
|
|
|
* @type { import('./async').reduceAsync }
|
2022-12-08 17:17:11 +01:00
|
|
|
*/
|
|
|
|
function reduceAsync(promiseArray) {
|
|
|
|
return (callback, initialValue) =>
|
|
|
|
promiseArray.reduce(async (previousPromise, currentValue, index) => {
|
|
|
|
const previousValue = await previousPromise;
|
|
|
|
return callback(previousValue, await currentValue, index);
|
|
|
|
}, Promise.resolve(initialValue));
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
mapAsync,
|
|
|
|
reduceAsync,
|
|
|
|
pipeAsync,
|
|
|
|
};
|