/** Promise.all + Array.map */ export const promiseMap = (arr: T[], map: (el: T, index?: number) => Res | Promise) => Promise.all(arr.map(map)) export const promiseMapDict = async ( dict: Record, map: (el: T, index?: number) => Res | Promise, ): Promise> => { const mappedEntries = await Promise.all(Object.entries(dict).map(async ([key, val]) => [key, await map(val)])) return Object.fromEntries(mappedEntries) } export const promiseMapToDict = async ( arr: T[], mapValue: (el: T, index?: number) => Res | Promise, mapKey: (el: T, index?: number) => string, ): Promise> => { const mappedEntries = await Promise.all(arr.map(async (el, index) => [mapKey(el, index), await mapValue(el, index)])) return Object.fromEntries(mappedEntries) } export const promiseMapPool = async ( arr: T[], map: (el: T, index?: number) => Promise, poolLimit: number, ): Promise => { const ret: Promise[] = [] const executing: Promise[] = [] for (const [index, item] of arr.entries()) { const p = Promise.resolve().then(() => map(item, index)) ret.push(p) if (poolLimit <= arr.length) { const e: any = p.then(() => executing.splice(executing.indexOf(e), 1)) executing.push(e) if (executing.length >= poolLimit) { await Promise.race(executing) } } } return Promise.all(ret) }