如何用fp-ts实现分页接口的顺序请求与结果合并?
使用fp-ts实现顺序分页请求并合并结果
类型定义与依赖导入
先明确数据类型和所需的fp-ts工具函数:
import { TaskEither, chain, fold, sequenceArray, map } from 'fp-ts/TaskEither'; import { pipe } from 'fp-ts/function'; // 定义书籍和分页响应类型 type Book = { /* 填充你的书籍结构字段 */ }; type BooksPageResponse = { totalItems: number; perPage: number; books: Book[]; }; // 假设你的getBooks返回带错误处理的异步任务,若无需错误处理可替换为Task declare const getBooks: (shelf: string, page: number) => TaskEither<Error, BooksPageResponse>;
核心实现逻辑
通过fp-ts的管道操作和任务串联,实现顺序分页请求与结果合并:
const fetchAllBooks = (shelf: string): TaskEither<Error, Book[]> => pipe( // 发起第一页请求 getBooks(shelf, 1), // 基于第一页响应生成后续请求并合并结果 chain(firstPage => { const totalPages = Math.ceil(firstPage.totalItems / firstPage.perPage); // 只有一页时直接返回结果 if (totalPages <= 1) { return TaskEither.right(firstPage.books); } // 生成剩余页码数组(从2到总页数) const remainingPages = Array.from({ length: totalPages - 1 }, (_, idx) => idx + 2); // 为每个剩余页码创建请求任务 const remainingPageTasks = remainingPages.map(page => getBooks(shelf, page)); // 顺序执行所有剩余请求,合并所有书籍数据 return pipe( sequenceArray(remainingPageTasks), map(responses => [ ...firstPage.books, ...responses.flatMap(res => res.books) ]) ); }) );
使用示例
调用并处理最终结果:
pipe( fetchAllBooks('my-shelf'), fold( error => () => console.error('分页请求失败:', error), allBooks => () => console.log('合并后的所有书籍:', allBooks) ) )();
关键说明
- 顺序执行保证:
sequenceArray会按数组顺序依次执行每个异步任务,确保分页请求串行发送,符合你的要求。 - 错误处理:使用
TaskEither统一处理请求过程中的错误,若你的getBooks不抛出错误,可替换为Task类型(对应导入Task的chain、map、sequenceArray)。 - 边界处理:判断总页数是否为1,避免不必要的后续请求,优化性能。
内容的提问来源于stack exchange,提问作者Bibiana Sebestianova
相关产品推荐
相关产品推荐

