总览:Reactor 响应式编程教程目录
Reactor 响应式编程教程 - 目录本教程共 8 章,采用循序渐进的方式,从基础概念到项目实战。 学习路径12345第一章 → 第二章 → 第三章 → 第四章 → 第五章 → 第六章 → 第七章 → 第八章 │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ▼ ▼ 入门 基础 订阅流程 线程调度 Sinks 错误处理 项目实战 (Why?) (What?) (How?) (Where?) (Control) (Safety) (Real) 章节简介📚 第一章:初识响应式编程 为什么需要响应式编程 传统同步 vs 响应式 Reactor 简介 适合场景分析 目标:理解”为什么”,建立背景认知 📚 第二章:Flux 与 Mono 基础 Flux 和 Mono...
第三章:订阅流程与生命周期
第三章:订阅流程与生命周期3.1 订阅到底做了什么?当你调用 subscribe() 时,Reactor 内部会发生什么? 123456Flux.just("A", "B", "C") .subscribe( element -> System.out.println("收到: " + element), error -> System.out.println("错误: " + error), () -> System.out.println("完成") ); 3.1.1 订阅流程图1234567891011121314151617181920212223┌─────────────────────────────────────────────────────────────────┐│ subscribe() 完整流程 ...
第一章:初识响应式编程
第一章:初识响应式编程1.1 什么是响应式编程?响应式编程(Reactive Programming)是一种面向数据流和变化传播的编程范式。 传统命令式 vs 响应式1234567891011121314151617181920212223// ============================================// 传统命令式编程(同步阻塞)// ============================================// 场景:调用 LLM API 获取回答public class SyncExample { public String chat(String question) { // 💡 线程在这里阻塞等待! // 假设 LLM 响应需要 5 秒,这 5 秒线程什么都干不了 String result = llmClient.call(question); // 只有 LLM 返回后,才能继续执行 return r...
第四章:线程调度 Schedulers
第四章:线程调度 Schedulers4.1 为什么需要线程调度?响应式编程的核心是非阻塞,但这不意味着不需要线程。 12345678910111213141516171819┌─────────────────────────────────────────────────────────────────┐│ 响应式编程的线程模型 │├─────────────────────────────────────────────────────────────────┤│ ││ 传统同步: 响应式: ││ ││ 线程 A: ...
第五章:Sinks.Many 手动控制数据流
第五章:Sinks.Many - 手动控制数据流5.1 什么是 Sinks?前面我们学习的 Flux/Mono 是声明式的:定义数据流和处理逻辑,由 Reactor 决定何时发出元素。 但在真实项目中,我们经常需要: 手动推送数据(比如 LLM 逐字返回时) 动态控制流的开始和结束 推送方和订阅方是分离的 这就需要 Sinks! Sinks vs Flux123456789101112131415// Flux: 声明式 - 我定义数据流,Reactor 帮我发Flux.just("A", "B", "C") .subscribe();// Sinks: 命令式 - 我手动控制何时发数据Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();// 订阅者sink.asFlux().subscribe();// 推送者(可以在任何时候、任何线程)sink.tryEmitNext("A"...
第二章:Flux 与 Mono 基础
第二章:Flux 与 Mono 基础2.1 什么是 Flux 和 Mono?Reactor 中有两个核心类型: 类型 元素数量 读作 典型场景 Flux<T> 0 到 N 个 “Flux” 列表、流式数据、SSE Mono<T> 0 或 1 个 “Mono” HTTP 响应、数据库单条记录 1234567// Flux:多个元素Flux<String> flux = Flux.just("A", "B", "C");// 发出: A → B → C → complete// Mono:单个元素(或空)Mono<String> mono = Mono.just("Hello");// 发出: Hello → complete 2.2 创建 Flux 的多种方式2.2.1 从固定值创建1234567891011121314// 1. Flux.just() - 最简单Flux<String> f1 = Flux.just(...
第十一章:事件处理与条件/列表渲染
11 — 事件处理与条件/列表渲染 这一章讲 JSX 里最常用的几种写法:事件、列表渲染、条件渲染。掌握这些,你就能读懂项目里所有「动态 UI」的部分。 1. 事件处理1.1 基础模式123456789function MyButton() { const handleClick = () => { console.log('点击了'); }; return <button onClick={handleClick}>点击</button>; // ↑ onClick 是驼峰 // ↑ 传函数引用} ⚠️ 不要写 onClick={handleClick()}(会立即执行),要写 onClick={handleClick}(点击时执行)。 1.2 内联箭头函数12<button onClick={() => console.log(...
第六章:深度研究智能体
06 - 深度研究智能体(PlanExecuteAgent)一、定位PlanExecuteAgent 是平台最复杂的智能体,实现了真正的自主研究能力。它通过 Plan → Execute → Critique 循环完成深度研究任务,能够自主: 澄清用户需求 生成研究主题 规划任务并并发执行 自我批判与反思 综合生成报告 二、核心创新点 能力 实现方式 智能并发控制 Semaphore(3) 控制同时进行的工具调用数 断点续传 OverAllState 维护完整状态机 自我批判 每轮执行后评估信息充分性,驱动多轮迭代 上下文压缩 contextCharLimit=50000 触发自动截断 工具重试 maxToolRetries=2 应对瞬时失败 三、四阶段执行流程12345678910111213141516171819202122232425262728 用户查询 ↓┌──────────────────────────────┐│ Phase 1: 需求澄清 ││ -...
第八章:Spring 集成与项目实战
第八章:Spring 集成与项目实战8.1 Spring WebFlux 基础Spring WebFlux 是 Spring 的响应式 Web 框架,完全支持 Reactor。 8.1.1 WebFlux vs MVC1234567891011121314151617// ============================================// 传统 Spring MVC(阻塞)// ============================================@RestControllerpublic class SyncController { @GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { // 线程阻塞等待数据库 return userService.findById(id); // 阻塞! } @GetMapp...
第七章:背压处理
第七章:背压处理 - 让快慢匹配7.1 什么是背压?背压(Backpressure)是指消费者处理速度跟不上生产者生产速度时的处理机制。 1234生产者(LLM 逐字返回): ████ ████ ████ ████ ████ → 每秒 20 个字消费者(前端渲染): ████ ████ → 每秒只能渲染 5 个字问题:积压越来越多,内存爆炸 💥 7.1.1 真实场景12345678910111213141516171819// 场景:LLM 快速返回,前端渲染慢LLMClient client = new LLMClient();// LLM 快速返回(每秒 50 个 token)Flux<String> tokenStream = client.streamChat("写一篇长文");// 前端渲染慢(每秒 5 个 token)tokenStream.subscribe(token -> { renderToScreen(token); // 渲染耗时操作 Thread.sleep(2...











