56 lines
1.7 KiB
JavaScript
Raw Normal View History

'use strict';
const { chunk } = require('lodash/fp');
function pipeAsync(...methods) {
return async (data) => {
let res = data;
for (const method of methods) {
res = await method(res);
}
return res;
};
}
/**
* @type { import('./async').mapAsync }
*/
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([]));
};
}
/**
* @type { import('./async').reduceAsync }
*/
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,
};