123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- import pLimit from 'p-limit';
- class EndError extends Error {
- constructor(value) {
- super();
- this.value = value;
- }
- }
- // The input can also be a promise, so we await it.
- const testElement = async (element, tester) => tester(await element);
- // The input can also be a promise, so we `Promise.all()` them both.
- const finder = async element => {
- const values = await Promise.all(element);
- if (values[1] === true) {
- throw new EndError(values[0]);
- }
- return false;
- };
- export default async function pLocate(
- iterable,
- tester,
- {
- concurrency = Number.POSITIVE_INFINITY,
- preserveOrder = true,
- } = {},
- ) {
- const limit = pLimit(concurrency);
- // Start all the promises concurrently with optional limit.
- const items = [...iterable].map(element => [element, limit(testElement, element, tester)]);
- // Check the promises either serially or concurrently.
- const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY);
- try {
- await Promise.all(items.map(element => checkLimit(finder, element)));
- } catch (error) {
- if (error instanceof EndError) {
- return error.value;
- }
- throw error;
- }
- }
|