名称: effect-patterns-project-setup–execution 描述: Effect-TS项目设置执行模式。在Effect-TS应用程序中处理项目设置执行时使用。
Effect-TS模式:项目设置执行
本技能提供了4个精选的Effect-TS模式,用于项目设置执行。 在处理以下相关任务时使用此技能:
- 项目设置执行
- Effect-TS应用程序中的最佳实践
- 真实世界的模式和解决方案
🟢 初学者模式
使用Effect.runSync执行同步效果
规则: 使用Effect.runSync执行同步效果。
良好示例:
import { Effect } from "effect";
// 简单的同步程序
const program1 = Effect.gen(function* () {
const n = 10;
const result = n * 2;
yield* Effect.log(`简单程序结果:${result}`);
return result;
});
// 运行简单程序
Effect.runSync(program1);
// 带日志的程序
const program2 = Effect.gen(function* () {
yield* Effect.logInfo("开始计算...");
const n = yield* Effect.sync(() => 10);
yield* Effect.logInfo(`获取数字:${n}`);
const result = yield* Effect.sync(() => n * 2);
yield* Effect.logInfo(`结果:${result}`);
return result;
});
// 带日志运行
Effect.runSync(program2);
// 带错误处理的程序
const program3 = Effect.gen(function* () {
yield* Effect.logInfo("开始除法...");
const n = yield* Effect.sync(() => 10);
const divisor = yield* Effect.sync(() => 0);
yield* Effect.logInfo(`尝试将${n}除以${divisor}...`);
return yield* Effect.try({
try: () => {
if (divisor === 0) throw new Error("不能除以零");
return n / divisor;
},
catch: (error) => {
if (error instanceof Error) {
return error;
}
return new Error("发生未知错误");
},
});
}).pipe(
Effect.catchAll((error) => Effect.logInfo(`发生错误:${error.message}`))
);
// 带错误处理运行
Effect.runSync(program3);
解释:
仅对完全同步的效果使用runSync。如果效果包含异步代码,则使用runPromise。
反模式:
不要对包含异步操作(如Effect.delay或Effect.promise)的效果使用runSync。这将导致运行时错误。
原理:
要执行保证为同步的Effect,使用Effect.runSync。这将直接返回成功值或抛出错误。
Effect.runSync是针对不涉及任何异步操作的效果的优化运行器。如果效果包含任何异步操作,runSync将抛出错误。
使用Effect.runPromise执行异步效果
规则: 使用Effect.runPromise执行异步效果。
良好示例:
import { Effect } from "effect";
const program = Effect.succeed("Hello, World!").pipe(Effect.delay("1 second"));
const promise = Effect.runPromise(program);
const programWithLogging = Effect.gen(function* () {
const result = yield* program;
yield* Effect.log(result); // 1秒后记录"Hello, World!"。
return result;
});
Effect.runPromise(programWithLogging);
解释:
Effect.runPromise执行你的效果并返回一个Promise,便于与现有的JavaScript异步工作流集成。
反模式:
永远不要在另一个Effect组合中调用runPromise。效果应在最终运行时一次组合在一起。
原理:
要执行可能为异步的Effect并获取其结果,使用Effect.runPromise。这应仅在应用程序的最外层进行。
Effect.runPromise是从Effect世界到Node.js和浏览器中基于Promise的世界的桥梁。如果效果成功,Promise解析;如果失败,Promise拒绝。
设置新的Effect项目
规则: 设置新的Effect项目。
良好示例:
// 1. 初始化项目(例如,`npm init -y`)
// 2. 安装依赖(例如,`npm install effect`, `npm install -D typescript tsx`)
// 3. 创建tsconfig.json,设置`"strict": true`
// 4. 创建src/index.ts
import { Effect } from "effect";
const program = Effect.log("Hello, World!");
Effect.runSync(program);
// 5. 运行程序(例如,`npx tsx src/index.ts`)
解释:
此设置确保你已准备好TypeScript和Effect,并启用严格类型检查以获得最大安全性和正确性。
反模式:
避免在tsconfig.json中禁用strict模式。使用"strict": false运行将导致你失去许多使Effect强大的类型安全保证。
原理:
要启动新的Effect项目,初始化标准的Node.js项目,添加effect和typescript作为依赖项,并创建一个启用严格模式的tsconfig.json文件。
正确的设置对于利用Effect强大的类型安全功能至关重要。使用TypeScript的strict模式是必须的。
🟠 高级模式
从层创建可重用运行时
规则: 从层创建可重用运行时。
良好示例:
import { Effect, Layer, Runtime } from "effect";
class GreeterService extends Effect.Service<GreeterService>()("Greeter", {
sync: () => ({
greet: (name: string) => Effect.sync(() => `Hello ${name}`),
}),
}) {}
const runtime = Effect.runSync(
Layer.toRuntime(GreeterService.Default).pipe(Effect.scoped)
);
// 在服务器中,你会为每个请求重用`run`。
Runtime.runPromise(runtime)(Effect.log("Hello"));
解释:
通过将层编译到Runtime中一次,你可以避免为每次效果执行重建依赖图。
反模式:
对于长时间运行的应用程序,避免在单个操作中提供层并运行效果。这会强制Effect在每次执行时重建依赖图。
原理:
对于需要运行多个效果的应用程序(例如,Web服务器),使用Layer.toRuntime(appLayer)将依赖图编译到单个可重用的Runtime对象中。
从层构建依赖图有一次性的成本。在应用程序启动时创建一次Runtime对于长时间运行的应用程序非常高效。