569 words
3 minutes
Effect 类型安全错误处理:2. 使用 Effect 进行 API 请求
2025-08-30 13:11:44
2025-12-24 23:45:46

让我们回到我们的 API 请求:

const main = async () => {
  const response = await fetch("https://pokeapi.co/api/v2/pokemon/garchomp/");
  const json = await response.json();
  return json;
};

main().then(console.log);

程序可以分为 2 个步骤:

  1. 执行 fetch 请求
  2. 从响应中提取 json
const fetchRequest = () => fetch("https://pokeapi.co/api/v2/pokemon/garchomp/");

const jsonResponse = (response: Response) => response.json();

const main = async () => {
  const response = await fetchRequest(); // 1️⃣
  const json = await jsonResponse(response); // 2️⃣
  return json;
};

main().then(console.log);

就像在纯 TypeScript 中一样,在 Effect 中处理异步或同步函数时,我们需要使用不同的 API。

因此,首先要考虑的是这两个都是异步操作。对于这些操作,我们可以使用 Effect.promise

Effect.promise任何异步操作的包装器。它返回一个包含调用异步函数结果的 Effect

对于同步操作,Effect.promise 的等价物是 Effect.sync

从原生 TypeScript 转换到 Effect 只需要用 Effect.promise 包装你的异步操作:

import { Effect } from "effect";

// 👇 Promise<Response>
const fetchRequest = 
  () => fetch("https://pokeapi.co/api/v2/pokemon/garchomp/");

/// 👇 Effect<Response>
const fetchRequest = Effect.promise(
  () => fetch("https://pokeapi.co/api/v2/pokemon/garchomp/")
);

注意我们是如何精确地将 Promise 包装Effect.promise 内部的:

// 👇 Promise<Response>
const promiseRequest = () => fetch("https://pokeapi.co/api/v2/pokemon/garchomp/");

/// 👇 Effect<Response>
const fetchRequest = Effect.promise(promiseRequest);

对于 response.json() 也是一样的:

import { Effect } from "effect";

/// 👇 Promise<unknown>
const jsonResponse = (response: Response) => response.json(); 

/// 👇 Effect<unknown>
const jsonResponse = (response: Response) => Effect.promise( 
  () => response.json() 
); 

我们从 Promise<Response> 转换到了 Effect<Response>

  • Promise<Response>急切的(异步操作立即执行
  • Effect<Response>惰性的(需要显式执行,并且可以根据需要执行多次)

理解 Effect#

到目前为止,我们所做的是用 Effect.promise 包装原生 API:

const fetchRequest = Effect.promise(
  () => fetch("https://pokeapi.co/api/v2/pokemon/garchomp/")
);

const jsonResponse = (response: Response) => Effect.promise(
  () => response.json()
);

我们之前说过,Effect 是步骤的组合:

  1. () => fetch("https://pokeapi.co/api/v2/pokemon/garchomp/")
  2. () => response.json()

根据我们使用的 API,我们告诉 Effect 如何执行包装的函数

Effect.promise 的意思是:“异步地执行这个函数并返回其结果”

但这与我们之前所做的有什么不同呢?有什么好处?

在接下来的课程中,我们将探索如何将 effect 组合在一起。Effect 的这种组合特性允许定义错误处理、超时、过滤等功能。

使用 Effect 构建应用程序就是定义如何处理每个步骤,然后将它们组合在一起

让我们接下来看看如何处理组合部分。

Effect 类型安全错误处理:2. 使用 Effect 进行 API 请求
https://0bipinnata0.my/posts/course/effect-beginners-complete-getting-started/type-safe-error-handling-with-effect/api-request-with-effect/
Author
0bipinnata0
Published at
2025-08-30 13:11:44