+30
| export interface Options { | ||
| /** | ||
| * Number of concurrently pending promises returned by `tester`. Minimum: `1`. | ||
| * | ||
| * @default Infinity | ||
| */ | ||
| readonly concurrency?: number; | ||
| /** | ||
| * Preserve `input` order when searching. | ||
| * | ||
| * Disable this to improve performance if you don't care about the order. | ||
| * | ||
| * @default true | ||
| */ | ||
| readonly preserveOrder?: boolean; | ||
| } | ||
| /** | ||
| * Get the first fulfilled promise that satisfies the provided testing function. | ||
| * | ||
| * @param input - An iterable of promises/values to test. | ||
| * @param tester - This function will receive resolved values from `input` and is expected to return a `Promise<boolean>` or `boolean`. | ||
| * @returns A `Promise` that is fulfilled when `tester` resolves to `true` or the iterable is done, or rejects if any of the promises reject. The fulfilled value is the current iterable value or `undefined` if `tester` never resolved to `true`. | ||
| */ | ||
| export default function pLocate<ValueType>( | ||
| input: Iterable<PromiseLike<ValueType> | ValueType>, | ||
| tester: (element: ValueType) => PromiseLike<boolean> | boolean, | ||
| options?: Options | ||
| ): Promise<ValueType | undefined>; |
+30
-13
@@ -11,25 +11,42 @@ 'use strict'; | ||
| // The input can also be a promise, so we `Promise.resolve()` it | ||
| const testElement = (el, tester) => Promise.resolve(el).then(tester); | ||
| // 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 = el => Promise.all(el).then(val => val[1] === true && Promise.reject(new EndError(val[0]))); | ||
| const finder = async element => { | ||
| const values = await Promise.all(element); | ||
| if (values[1] === true) { | ||
| throw new EndError(values[0]); | ||
| } | ||
| module.exports = (iterable, tester, opts) => { | ||
| opts = Object.assign({ | ||
| return false; | ||
| }; | ||
| const pLocate = async (iterable, tester, options) => { | ||
| options = { | ||
| concurrency: Infinity, | ||
| preserveOrder: true | ||
| }, opts); | ||
| preserveOrder: true, | ||
| ...options | ||
| }; | ||
| const limit = pLimit(opts.concurrency); | ||
| const limit = pLimit(options.concurrency); | ||
| // Start all the promises concurrently with optional limit | ||
| const items = [...iterable].map(el => [el, limit(testElement, el, tester)]); | ||
| const items = [...iterable].map(element => [element, limit(testElement, element, tester)]); | ||
| // Check the promises either serially or concurrently | ||
| const checkLimit = pLimit(opts.preserveOrder ? 1 : Infinity); | ||
| const checkLimit = pLimit(options.preserveOrder ? 1 : Infinity); | ||
| return Promise.all(items.map(el => checkLimit(finder, el))) | ||
| .then(() => {}) | ||
| .catch(err => err instanceof EndError ? err.value : Promise.reject(err)); | ||
| try { | ||
| await Promise.all(items.map(element => checkLimit(finder, element))); | ||
| } catch (error) { | ||
| if (error instanceof EndError) { | ||
| return error.value; | ||
| } | ||
| throw error; | ||
| } | ||
| }; | ||
| module.exports = pLocate; | ||
| module.exports.default = pLocate; |
+10
-8
| { | ||
| "name": "p-locate", | ||
| "version": "3.0.0", | ||
| "version": "4.0.0", | ||
| "description": "Get the first fulfilled promise that satisfies the provided testing function", | ||
@@ -13,9 +13,10 @@ "license": "MIT", | ||
| "engines": { | ||
| "node": ">=6" | ||
| "node": ">=8" | ||
| }, | ||
| "scripts": { | ||
| "test": "xo && ava" | ||
| "test": "xo && ava && tsd-check" | ||
| }, | ||
| "files": [ | ||
| "index.js" | ||
| "index.js", | ||
| "index.d.ts" | ||
| ], | ||
@@ -46,8 +47,9 @@ "keywords": [ | ||
| "devDependencies": { | ||
| "ava": "*", | ||
| "delay": "^3.0.0", | ||
| "ava": "^1.3.1", | ||
| "delay": "^4.1.0", | ||
| "in-range": "^1.0.0", | ||
| "time-span": "^2.0.0", | ||
| "xo": "*" | ||
| "time-span": "^3.0.0", | ||
| "tsd-check": "^0.3.0", | ||
| "xo": "^0.24.0" | ||
| } | ||
| } |
+4
-2
@@ -48,4 +48,6 @@ # p-locate [](https://travis-ci.org/sindresorhus/p-locate) | ||
| Type: `Iterable<Promise|any>` | ||
| Type: `Iterable<Promise | unknown>` | ||
| An iterable of promises/values to test. | ||
| #### tester(element) | ||
@@ -55,3 +57,3 @@ | ||
| Expected to return a `Promise<boolean>` or boolean. | ||
| This function will receive resolved values from `input` and is expected to return a `Promise<boolean>` or `boolean`. | ||
@@ -58,0 +60,0 @@ #### options |
6497
28.53%5
25%68
161.54%91
2.25%6
20%