Skip to content

Commit 211f73f

Browse files
committed
Renamed find*
1 parent 3fec1e4 commit 211f73f

File tree

8 files changed

+85
-178
lines changed

8 files changed

+85
-178
lines changed

modern-async.d.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ declare module "findIndexLimit" {
6666
declare module "every" {
6767
export default every;
6868
function every<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean, queueOrConcurrency: Queue | number): Promise<boolean>;
69+
import Queue from "Queue";
6970
}
7071
declare module "toArray" {
7172
export default toArray;
@@ -83,16 +84,13 @@ declare module "filterGenerator" {
8384
}
8485
declare module "filter" {
8586
export default filter;
86-
function filter<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean, queueOrConcurrency: Queue | number): Promise<V[]>;
87-
}
88-
declare module "findLimit" {
89-
export default findLimit;
90-
function findLimit<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean, queueOrConcurrency: Queue | number, ordered?: boolean): Promise<V>;
87+
function filter<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean, queueOrConcurrency?: Queue | number): Promise<V[]>;
9188
import Queue from "Queue";
9289
}
9390
declare module "find" {
9491
export default find;
95-
function find<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean, ordered?: boolean): Promise<V>;
92+
function find<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean, queueOrConcurrency?: Queue | number, ordered?: boolean): Promise<V>;
93+
import Queue from "Queue";
9694
}
9795
declare module "findIndex" {
9896
export default findIndex;
@@ -102,10 +100,6 @@ declare module "findIndexSeries" {
102100
export default findIndexSeries;
103101
function findIndexSeries<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean): Promise<number>;
104102
}
105-
declare module "findSeries" {
106-
export default findSeries;
107-
function findSeries<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<boolean> | boolean): Promise<V>;
108-
}
109103
declare module "forEachLimit" {
110104
export default forEachLimit;
111105
function forEachLimit<V>(iterable: Iterable<V> | AsyncIterable<V>, iteratee: (value: V, index: number, iterable: Iterable<V> | AsyncIterable<V>) => Promise<void> | void, queueOrConcurrency: Queue | number): Promise<void>;
@@ -222,8 +216,6 @@ declare module "modern-async" {
222216
export { default as findIndex } from "findIndex";
223217
export { default as findIndexLimit } from "findIndexLimit";
224218
export { default as findIndexSeries } from "findIndexSeries";
225-
export { default as findLimit } from "findLimit";
226-
export { default as findSeries } from "findSeries";
227219
export { default as forEach } from "forEach";
228220
export { default as forEachLimit } from "forEachLimit";
229221
export { default as forEachSeries } from "forEachSeries";

src/find.mjs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11

2-
import findLimit from './findLimit.mjs'
2+
import findInternal from './findInternal.mjs'
3+
import Queue from './Queue.mjs'
34

45
/**
56
* Returns the first element of an iterable that passes an asynchronous truth test.
67
*
7-
* The calls to `iteratee` will run in parallel.
8+
* The calls to `iteratee` will be performed in a queue to limit the concurrency of these calls.
89
*
9-
* In case of exception in one of the `iteratee` calls the promise returned by this function will be
10-
* rejected with the exception. In the very specific case where a result is found and an
10+
* Whenever a result is found, all the remaining tasks will be cancelled as long
11+
* as they didn't started already. In case of exception in one of the `iteratee` calls the promise
12+
* returned by this function will be rejected with the exception and the remaining pending
13+
* tasks will also be cancelled. In the very specific case where a result is found and an
1114
* already started task throws an exception that exception will be plainly ignored.
1215
*
1316
* @param {Iterable | AsyncIterable} iterable An iterable or async iterable object.
@@ -16,23 +19,28 @@ import findLimit from './findLimit.mjs'
1619
* * `value`: The current value to process
1720
* * `index`: The index in the iterable. Will start from 0.
1821
* * `iterable`: The iterable on which the operation is being performed.
22+
* @param {Queue | number} queueOrConcurrency If a queue is specified it will be used to schedule the calls to
23+
* `iteratee`. If a number is specified it will be used as the concurrency of a Queue that will be created
24+
* implicitly for the same purpose. Defaults to `1`.
1925
* @param {boolean} [ordered] If true this function will return on the first element in the iterable
2026
* order for which `iteratee` returned true. If false it will be the first in time.
2127
* @returns {Promise<any | undefined>} A promise that will be resolved with the first found value or rejected if one of the
2228
* `iteratee` calls throws an exception before finding a value. If no value is found it will return `undefined`.
2329
* @example
2430
* import { find, sleep } from 'modern-async'
2531
*
26-
* const array = [1, 2, 3]
32+
* const array = [1, 2, 3, 4, 5]
2733
* const result = await find(array, async (v) => {
28-
* // these calls will be performed in parallel
34+
* // these calls will be performed in parallel with a maximum of 3
35+
* // concurrent calls
2936
* await sleep(Math.random() * 10) // waits a random amount of time between 0ms and 10ms
3037
* return v % 2 === 1
31-
* })
38+
* }, 3)
3239
* console.log(result) // prints 1
3340
*/
34-
async function find (iterable, iteratee, ordered = false) {
35-
return findLimit(iterable, iteratee, Number.POSITIVE_INFINITY, ordered)
41+
async function find (iterable, iteratee, queueOrConcurrency = 1, ordered = false) {
42+
const result = (await findInternal(iterable, iteratee, queueOrConcurrency, ordered))[1]
43+
return result
3644
}
3745

3846
export default find

src/find.test.mjs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,45 @@ import Deferred from './Deferred.mjs'
55
import { range } from 'itertools'
66

77
test('find', async () => {
8+
const arr = ['a', 'b', 'c']
9+
const callCount = {}
10+
;[...range(3)].forEach((i) => { callCount[i] = 0 })
11+
const d = new Deferred()
12+
const ds = [...range(3)].map(() => new Deferred())
13+
const p = find(arr, async (v, i) => {
14+
callCount[i] += 1
15+
ds[i].resolve()
16+
await d.promise
17+
return v === 'b'
18+
}, 1)
19+
await ds[0].promise
20+
expect(callCount[0]).toBe(1)
21+
expect(callCount[1]).toBe(0)
22+
expect(callCount[2]).toBe(0)
23+
d.resolve()
24+
const res = await p
25+
expect(res).toBe('b')
26+
expect(callCount[0]).toBe(1)
27+
expect(callCount[1]).toBe(1)
28+
expect(callCount[2]).toBe(0)
29+
})
30+
31+
test('find not found', async () => {
32+
const arr = ['a', 'b', 'c']
33+
const callCount = {}
34+
;[...range(3)].forEach((i) => { callCount[i] = 0 })
35+
const d = new Deferred()
36+
const p = find(arr, async (v, i) => {
37+
callCount[i] += 1
38+
await d.promise
39+
return v === 'd'
40+
}, 1)
41+
d.resolve()
42+
const res = await p
43+
expect(res).toBe(arr.find((v) => v === 'd'))
44+
})
45+
46+
test('find infinite concurrency', async () => {
847
const arr = ['a', 'b', 'c']
948
const callCount = {}
1049
;[...range(3)].forEach((i) => { callCount[i] = 0 })
@@ -15,7 +54,7 @@ test('find', async () => {
1554
ds[i].resolve()
1655
await d.promise
1756
return v === 'b'
18-
})
57+
}, Number.POSITIVE_INFINITY)
1958
await ds[2].promise
2059
expect(callCount[0]).toBe(1)
2160
expect(callCount[1]).toBe(1)
@@ -27,3 +66,27 @@ test('find', async () => {
2766
expect(callCount[1]).toBe(1)
2867
expect(callCount[2]).toBe(1)
2968
})
69+
70+
test('find concurrency 1', async () => {
71+
const arr = ['a', 'b', 'c']
72+
const callCount = {}
73+
;[...range(3)].forEach((i) => { callCount[i] = 0 })
74+
const d = new Deferred()
75+
const ds = [...range(3)].map(() => new Deferred())
76+
const p = find(arr, async (v, i) => {
77+
callCount[i] += 1
78+
ds[i].resolve()
79+
await d.promise
80+
return v === 'b'
81+
})
82+
await ds[0].promise
83+
expect(callCount[0]).toBe(1)
84+
expect(callCount[1]).toBe(0)
85+
expect(callCount[2]).toBe(0)
86+
d.resolve()
87+
const res = await p
88+
expect(res).toBe('b')
89+
expect(callCount[0]).toBe(1)
90+
expect(callCount[1]).toBe(1)
91+
expect(callCount[2]).toBe(0)
92+
})

src/findLimit.mjs

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/findLimit.test.mjs

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/findSeries.mjs

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/findSeries.test.mjs

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/modern-async.mjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ export { default as find } from './find.mjs'
1414
export { default as findIndex } from './findIndex.mjs'
1515
export { default as findIndexLimit } from './findIndexLimit.mjs'
1616
export { default as findIndexSeries } from './findIndexSeries.mjs'
17-
export { default as findLimit } from './findLimit.mjs'
18-
export { default as findSeries } from './findSeries.mjs'
1917
export { default as forEach } from './forEach.mjs'
2018
export { default as forEachLimit } from './forEachLimit.mjs'
2119
export { default as forEachSeries } from './forEachSeries.mjs'

0 commit comments

Comments
 (0)