链式触发器
某些需求接口是并发处理,多个接口一并触发,这种一般通过 Promise.all 处理,但是有时候需要链式触发,也就是后一个根据前一个结果处理
所以就有了下面这个代码
/**
* 链式触发器的配置选项
* @property {number} [timeout] - 超时时间(毫秒),默认5000ms
* @property {(result: any, index: number) => Promise<any>} [middleware] - 中间件函数,用于处理每个promise的结果
*/
type ChainTriggerOptions = {
timeout?: number;
middleware?: (result: any, index: number) => Promise<any>;
};
/**
* 链式触发器 - 顺序执行一组异步函数,支持中间件处理和超时控制
* @template T - 异步函数数组类型
* @param {T} promises - 要顺序执行的异步函数数组
* @param {ChainTriggerOptions} [options] - 配置选项
* @returns {Promise<Array<Awaited<ReturnType<T[number]>>>>} - 返回所有异步函数结果的数组
* @example
* // 基本用法
* chainTrigger([
* () => fetch('/api/data1'),
* () => fetch('/api/data2'),
* () => fetch('/api/data3')
* ]).then(results => {
* console.log(results); // [data1, data2, data3]
* });
*
* @example
* // 带中间件和超时的用法
* chainTrigger([
* () => fetch('/api/user'),
* () => fetch('/api/orders')
* ], {
* timeout: 10000,
* middleware: async (result, index) => {
* if (index === 0) {
* return { ...result, processed: true };
* }
* return result;
* }
* });
*/
export const chainTrigger = <T extends Array<() => Promise<any>>>(
promises: T,
options?: ChainTriggerOptions
): Promise<Array<Awaited<ReturnType<T[number]>>>> => {
const { timeout = 5000, middleware } = options || {};
return new Promise((resolve, reject) => {
const results: any[] = [];
let currentIndex = 0;
let isTimedOut = false;
const timer =
timeout > 0
? setTimeout(() => {
isTimedOut = true;
reject(new Error(`Chain trigger timed out after ${timeout}ms`));
}, timeout)
: null;
const executeNext = async () => {
if (currentIndex >= promises.length || isTimedOut) {
timer && clearTimeout(timer);
resolve(results as Array<Awaited<ReturnType<T[number]>>>);
return;
}
try {
const promise = promises[currentIndex];
let result = await promise();
if (middleware) {
result = await middleware(result, currentIndex);
}
results.push(result);
currentIndex++;
executeNext();
} catch (error) {
timer && clearTimeout(timer);
reject(error);
}
};
executeNext();
});
};
可以根据示例直接使用,简洁简单