实现思路
- 类型推断:利用 TypeScript 的泛型和类型推断机制,使得每个回调函数的第一个参数类型能根据前一个回调函数的返回值类型动态确定。
- 错误处理:在每个回调函数中处理可能出现的错误,并将错误传递给后续回调函数。
- 循环依赖处理:通过在运行时记录已经处理过的回调函数,避免类型循环依赖导致的无限递归。
关键步骤
- 定义泛型:使用泛型来表示回调函数的参数和返回值类型。
- 遍历回调数组:按顺序依次执行每个回调函数。
- 类型检查与错误处理:在执行回调函数时,检查是否有错误,并根据前一个回调的返回值类型动态推断当前回调的参数类型。
- 循环依赖检测:维护一个已执行回调的集合,在执行每个回调前检查是否已执行过,避免循环依赖。
代码实现
function CompositeOperation<TCallbacks extends ((arg: any, err?: Error) => any)[]>(callbacks: TCallbacks): Promise<any> {
return new Promise((resolve, reject) => {
const executedCallbacks = new Set();
let currentIndex = 0;
let prevResult: any;
function executeNext() {
if (currentIndex >= callbacks.length) {
resolve(prevResult);
return;
}
const callback = callbacks[currentIndex];
const callbackKey = callback.toString();
if (executedCallbacks.has(callbackKey)) {
reject(new Error('循环依赖检测到'));
return;
}
executedCallbacks.add(callbackKey);
try {
callback(prevResult, (err: Error) => {
if (err) {
reject(err);
} else {
prevResult = callback(prevResult);
currentIndex++;
executeNext();
}
});
} catch (error) {
reject(error);
}
}
executeNext();
});
}
调用示例
const operation = CompositeOperation([
(arg, err) => {
if (err) {
console.error(err);
}
return {id: 1};
},
(arg, err) => {
if (err) {
console.error(err);
}
return arg.id + 1;
}
]);
operation.then(result => {
console.log(result);
}).catch(error => {
console.error(error);
});