@shutootaki/gwm
Version:
git worktree manager CLI
116 lines • 3.6 kB
JavaScript
/**
* 非同期処理共通ユーティリティ
*/
/**
* 並列実行制御付きでタスクを実行する
* @param tasks 実行するタスクの配列
* @param concurrency 最大並列数
* @returns すべてのタスクの結果
*/
export async function executeWithConcurrency(tasks, concurrency) {
const results = [];
const active = [];
for (let i = 0; i < tasks.length; i++) {
const task = tasks[i];
const promise = task().then((result) => {
results[i] = result;
const index = active.indexOf(promise);
if (index >= 0) {
active.splice(index, 1);
}
});
active.push(promise);
if (active.length >= concurrency) {
await Promise.race(active);
}
}
await Promise.all(active);
return results;
}
/**
* タイムアウト付きでPromiseを実行する
* @param promise 実行するPromise
* @param timeoutMs タイムアウト時間(ミリ秒)
* @returns 結果またはタイムアウトエラー
*/
export async function withTimeout(promise, timeoutMs) {
return Promise.race([
promise,
new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeoutMs)),
]);
}
/**
* 失敗時にリトライする
* @param fn 実行する関数
* @param maxRetries 最大リトライ回数
* @param delayMs リトライ間隔(ミリ秒)
* @returns 結果
*/
export async function withRetry(fn, maxRetries = 3, delayMs = 1000) {
let lastError = new Error('Unknown error');
for (let i = 0; i <= maxRetries; i++) {
try {
return await fn();
}
catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
if (i < maxRetries) {
await sleep(delayMs);
}
}
}
throw lastError;
}
/**
* 指定時間待機する
* @param ms 待機時間(ミリ秒)
*/
export function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* 配列の各要素に対して非同期関数を順次実行する
* @param items 処理する配列
* @param fn 各要素に適用する非同期関数
* @returns 結果の配列
*/
export async function mapSequential(items, fn) {
const results = [];
for (let i = 0; i < items.length; i++) {
results.push(await fn(items[i], i));
}
return results;
}
/**
* 配列の各要素に対して非同期関数を並列実行する(制限あり)
* @param items 処理する配列
* @param fn 各要素に適用する非同期関数
* @param concurrency 最大並列数
* @returns 結果の配列
*/
export async function mapConcurrent(items, fn, concurrency = 4) {
const tasks = items.map((item, index) => () => fn(item, index));
return executeWithConcurrency(tasks, concurrency);
}
/**
* すべてのPromiseが完了するまで待機し、成功・失敗を区別する
* @param promises 実行するPromiseの配列
* @returns 成功・失敗の結果
*/
export async function allSettled(promises) {
const results = await Promise.allSettled(promises);
const succeeded = [];
const failed = [];
results.forEach((result) => {
if (result.status === 'fulfilled') {
succeeded.push(result.value);
}
else {
failed.push(result.reason instanceof Error
? result.reason
: new Error(String(result.reason)));
}
});
return { succeeded, failed };
}
//# sourceMappingURL=async.js.map