promise-parallel-throttle
同時に実行できるPromiseの数を抑えたもの
https://github.com/DJWassink/Promise-parallel-throttle
/ci7lus/pdfの全てのページをGyazoにアップロードしてScrapboxに貼り付けるUserScriptで存在を知った
2023-01-11 05:58:24 再実装
TypeScriptで書く
arrow functionsにする
code:mod.ts
export type Fn = <T>() => Promise<T>;
export const makeThlottle = <T>(max: number): (job: Fn<T>) => Promise<T> => {
const queue: [
Fn<T>,
(value: T) => void,
(error: unknown) => void
][] = [];
const pendings = new Set<Promise<T>>();
const runNext = async (prev: Promise<T>) => {
pendings.delete(prev);
const task = queue.shift();
if (!task) return;
const promise = task0()
.then((result) => task1(result))
.catch((error) => task2(error));
pendings.add(promise);
promise.finally(() => runNext(task0));
};
return (job) => {
if (pendings.size < max) {
const promise = job();
pendings.add(promise);
promise.finally(() => runNext(promise));
return promise;
}
return new Promise((resolve, reject) => {
queue.push(job, resolve, reject);
});
};
};
2021-03-13 05:59:58
takker.iconなりに書いたpromise-parallel-throttleの実装
promiseCallbacksにPromiseを生成する関数を渡す
Promiseそのものではなく、生成する関数を使うことで、Promiseの開始を遅延できる
code:script.js
export async function throttle(promiseCallbacks, {maxInProgress = undefined} = {}) {
if (!maxInProgress || maxInProgress < 0
|| promiseCallbacks.length <= maxInProgress)
return await Promise.all(promiseCallbacks.map(callback => callback()));
let progressList = promiseCallbacks.map(_ => false);
let result = [];
await Promise.all(...Array(maxInProgress).keys()
.map(async index => {
do {
//console.log(Executing index ${index}...);
progressListindex = true;
resultindex = await promiseCallbacksindex();
//console.log(Executed ${index}.);
index = progressList.findIndex(state => !state);
} while(index !== -1)
}));
return result;
}
code:script.d.ts
export function throttle<T, U>(
promiseCallbacks: ((...params: T) => Promise<U>)[],
options?: {maxInProgress?: number},
): Promise<U[]>;
#2024-12-19 23:40:25
#2023-01-11 06:19:55
#2021-07-01 21:25:55
#2021-03-13 06:00:10
#2021-01-28
#2021-01-24