UNPKG

p-iterate

Version:

Iterate over promises as they're fulfilled.

70 lines 2.31 kB
export async function* pIter(promises) { // Typescript incorrectly narrows `state` on the assumption that it doesn't // leak, so we manually widen it to its full type range. // eslint-disable-next-line @typescript-eslint/consistent-type-assertions let state = { label: 'accumulating', values: [] }; let count = 0; for (const promise of promises) { count++; /* eslint-disable @typescript-eslint/no-loop-func */ Promise.resolve(promise) .then((value) => { if (state.label === 'yielded') { state.resolve(value); state = { label: 'accumulating', values: [] }; } else if (state.label === 'accumulating') { state.values.push(value); } }) .catch((error) => { if (state.label === 'yielded') { state.reject(error); } else if (state.label === 'accumulating') { state = { label: 'rejected', reason: error }; } }); /* eslint-enable @typescript-eslint/no-loop-func */ } while (count > 0) { count--; if (state.label === 'rejected') { throw state.reason; } else if (state.label === 'accumulating') { if (state.values.length > 0) { yield state.values.pop(); } else { // eslint-disable-next-line @typescript-eslint/no-loop-func yield new Promise((resolve, reject) => { state = { label: 'yielded', resolve, reject }; }); } } } } function* map(iterable, fn) { let index = 0; for (const item of iterable) { yield fn(item, index++); } } export function pIterSettled(promises) { return pIter(map(promises, async (promise, index) => { try { return { status: 'fulfilled', value: await promise, index }; } catch (error) { return { status: 'rejected', reason: error, index }; } })); } export function pIterEnumerated(promises) { return pIter(map(promises, async (promise, index) => [ index, await Promise.resolve(promise), ])); } //# sourceMappingURL=index.js.map