1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- 'use strict';
- const pLimit = require('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;
- };
-
- const pLocate = async (iterable, tester, options) => {
- options = {
- concurrency: Infinity,
- preserveOrder: true,
- ...options
- };
-
- const limit = pLimit(options.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(options.preserveOrder ? 1 : Infinity);
-
- try {
- await Promise.all(items.map(element => checkLimit(finder, element)));
- } catch (error) {
- if (error instanceof EndError) {
- return error.value;
- }
-
- throw error;
- }
- };
-
- module.exports = pLocate;
|