函数顺序调用
需求场景
- 需要按照顺序调用多个函数,并且每个函数都需要等待前一个函数执行完成后再执行
- 如果前一个函数执行成功(返回 true),继续执行下一个函数,否则(返回 false),后续函数不再执行
- 并且同时支持同步和异步函数
实现方式
- 使用 for 循环,依次执行每个函数,使用 await 继发执行 (Unexpected
await
inside a loop.eslintno-await-in-loop )
ts
// for循环中 await 继发执行
async function callMethodsSequentially(methods: (() => boolean | Promise<boolean>)[]) {
for (const method of methods) {
const result = await Promise.resolve(method()); // 确保同步和异步方法都能被正确处理
if (result === false) {
return false;
}
}
return true;
}
- 使用 Promise.all 并发执行多个函数(无法控制每个函数的执行顺序)
ts
async function callMethodsSequentiallyPromiseAll(methods: (() => boolean | Promise<boolean>)[]) {
const results = await Promise.all(methods.map(method =>
Promise.resolve(method())
));
for (const result of results) {
if (result === false) {
return false;
}
}
return true;
}
- 使用 reduce 处理 继发处理
ts
async function callMethodsSequentiallReduce(methods: (() => boolean | Promise<boolean>)[]) {
let finalResult = true
await methods.reduce(async (promise, method) => {
await promise
if (!finalResult) {
return
}
const result = await method()
if (result === false) {
finalResult = false
}
}, Promise.resolve())
return finalResult
}
- 使用生成器, yield 继发处理,while循环 (Unexpected
await
inside a loop.eslintno-await-in-loop)
ts
// 生成器处理 yield 继发处理 while循环
async function callMethodsSequentiallyGeneratorYieldWhile(methods: (() => boolean | Promise<boolean>)[]) {
function* methodGenerator() {
for (const method of methods) {
const result = yield method();
if (result === false) {
return false;
}
}
return true;
}
const generator = methodGenerator();
let result = generator.next();
while (!result.done) {
const promise = Promise.resolve(result.value);
const resolvedResult = await promise;
result = generator.next(resolvedResult);
}
return result.value;
}
- 使用生成器, yield 继发处理,递归函数
ts
// 生成器处理 yield 继发处理 递归函数
export async function callMethodsSequentiallyGeneratorYieldRecursive(methods: (() => boolean | Promise<boolean>)[]) {
function* methodGenerator(): Generator<boolean | Promise<boolean>, boolean, boolean> {
for (const method of methods) {
const result: boolean | Promise<boolean> = yield method();
if (result === false) {
return false;
}
}
return true;
}
const generator = methodGenerator();
let result = generator.next();
async function processNext(): Promise<boolean> {
if (result.done) {
return result.value;
}
const promise = Promise.resolve(result.value);
const resolvedResult: boolean = await promise;
result = generator.next(resolvedResult);
return processNext();
}
return processNext();
}