MCPcopy Create free account
hub / github.com/denoland/std / pooledMap

Function pooledMap

async/pool.ts:41–117  ·  view source on GitHub ↗
(
  poolLimit: number,
  array: Iterable<T> | AsyncIterable<T>,
  iteratorFn: (data: T) => Promise<R>,
)

Source from the content-addressed store, hash-verified

39 * @throws {RangeError} If `poolLimit` is not a positive integer.
40 */
41export function pooledMap<T, R>(
42 poolLimit: number,
43 array: Iterable<T> | AsyncIterable<T>,
44 iteratorFn: (data: T) => Promise<R>,
45): AsyncIterableIterator<R> {
46 if (!Number.isInteger(poolLimit) || poolLimit < 1) {
47 throw new RangeError("'poolLimit' must be a positive integer");
48 }
49
50 const res = new TransformStream<Promise<R>, R>({
51 async transform(
52 p: Promise<R>,
53 controller: TransformStreamDefaultController<R>,
54 ) {
55 try {
56 const s = await p;
57 controller.enqueue(s);
58 } catch (e) {
59 if (
60 e instanceof AggregateError &&
61 e.message === ERROR_WHILE_MAPPING_MESSAGE
62 ) {
63 controller.error(e as unknown);
64 }
65 }
66 },
67 });
68 // Start processing items from the iterator
69 (async () => {
70 const writer = res.writable.getWriter();
71 const executing: Array<Promise<unknown>> = [];
72 try {
73 for await (const item of array) {
74 const p = Promise.resolve().then(() => iteratorFn(item));
75 // Only write on success. If we `writer.write()` a rejected promise,
76 // that will end the iteration. We don't want that yet. Instead let it
77 // fail the race, taking us to the catch block where all currently
78 // executing jobs are allowed to finish and all rejections among them
79 // can be reported together.
80 writer.write(p);
81 const e: Promise<unknown> = p.then(() =>
82 executing.splice(executing.indexOf(e), 1)
83 );
84 executing.push(e);
85 if (executing.length >= poolLimit) {
86 await Promise.race(executing);
87 }
88 }
89 // Wait until all ongoing events have processed, then close the writer.
90 await Promise.all(executing);
91 writer.close();
92 } catch {
93 const errors = [];
94 for (const result of await Promise.allSettled(executing)) {
95 if (result.status === "rejected") {
96 errors.push(result.reason);
97 }
98 }

Callers 1

pool_test.tsFile · 0.90

Calls 5

writeMethod · 0.65
closeMethod · 0.65
readMethod · 0.65
pushMethod · 0.45
releaseLockMethod · 0.45

Tested by

no test coverage detected