在 TypeScript 中,高阶函数(Higher-Order Functions)是指可以接受一个或多个函数作为参数,并且返回一个函数的函数。异步函数能够通过 asyncawait 关键字来使用,以处理异步操作,例如网络请求、文件操作或者数据库查询。

这里,我将展示一个使用高阶函数和异步函数的实用例子:一个通用的错误处理器(Error Handler)高阶函数,它可用于自动处理任何给定异步函数的错误。

例子一:通用的异步错误处理器

假设我们有一些操作是异步的,例如从 API 获取数据。我们不希望每次调用这个操作时都手动处理错误,所以我们可以创建一个通用的错误处理器。

// 我们先定义一个异步示例操作,假设它是一个从 API 获取用户数据的函数
async function fetchUserData(userId: string): Promise<any> {
  // 模拟一个异步 API 请求
  if (userId === "notfound") {
    throw new Error("User not found");
  }
  return { id: userId, name: "John Doe" };
}
 
// 高阶函数:接受一个异步函数作为参数,返回一个带有错误处理的新函数
function withErrorHandler<T extends (...args: any[]) => Promise<any>>(asyncFunc: T) {
  return async (...args: Parameters<T>): Promise<ReturnType<T> | { error: any }> => {
    try {
      // 调用传入的异步函数,并返回其结果
      const result = await asyncFunc(...args);
      return result;
    } catch (error) {
      // 处理错误,并返回一个错误对象
      console.error("An error occurred:", error);
      return { error };
    }
  };
}
 
// 使用高阶函数包装 fetchUserData
const safeFetchUserData = withErrorHandler(fetchUserData);
 
// 测试函数
async function test() {
  const user1 = await safeFetchUserData("123");
  console.log("User 1:", user1);
 
  const user2 = await safeFetchUserData("notfound");
  console.log("User 2:", user2);
}
 
test();

在这个例子中,我们实现了一个通用的错误处理器 withErrorHandler。这个高阶函数接受一个异步函数 asyncFunc,并返回一个新的异步函数,这个新函数对传入的函数进行调用,并在发生错误时处理它。

例子二:带有重试逻辑的异步高阶函数

接下来,我们扩展一下这个例子,创建一个带有重试逻辑的高阶函数。如果操作失败,它将重新尝试几次。

// 高阶函数:接受一个异步函数作为参数,同时添加重试逻辑
function withRetry<T extends (...args: any[]) => Promise<any>>(asyncFunc: T, retries: number) {
  return async (...args: Parameters<T>): Promise<ReturnType<T>> => {
    let attempt = 0;
    while (attempt < retries) {
      try {
        // 调用传入的异步函数,并返回其结果
        const result = await asyncFunc(...args);
        return result;
      } catch (error) {
        attempt++;
        console.warn(`Attempt ${attempt} failed:`, error);
        if (attempt >= retries) {
          throw new Error(`All ${retries} retry attempts failed`);
        }
      }
    }
  };
}
 
// 使用高阶函数包装 fetchUserData
const fetchUserDataWithRetry = withRetry(fetchUserData, 3);
 
// 测试函数
async function testWithRetry() {
  try {
    const user1 = await fetchUserDataWithRetry("123");
    console.log("User 1:", user1);
  } catch (error) {
    console.error("Failed to fetch User 1:", error);
  }
 
  try {
    const user2 = await fetchUserDataWithRetry("notfound");
    console.log("User 2:", user2);
  } catch (error) {
    console.error("Failed to fetch User 2:", error);
  }
}
 
testWithRetry();

在这个扩展示例中,withRetry 是一个带有重试逻辑的高阶函数。它会尝试调用传入的异步函数,如果发生错误,则会重试指定次数。在所有重试都失败后,它将会抛出一个错误。

总结

高阶函数是函数式编程中的重要概念,它可以极大地提高代码的复用性和抽象能力。通过这些示例,你可以看到如何在 TypeScript 中使用异步函数和高阶函数来创建更健壮和灵活的代码。希望这些例子对你有所帮助!如果有进一步的问题或更复杂的场景需要讨论,请随时提问。