Flutter中如何基于RxDart实现带分页的API调用?
RxDart 实现 Tenor API 同关键词分页加载方案
核心调整思路
- 原有逻辑仅支持传入搜索关键词触发新搜索,我们需要扩展事件类型,同时支持「新搜索」和「加载下一页」两种操作
- 本地存储两个状态:上一次生效的搜索关键词、上一次请求返回的
TenorResponse实例,用于调用分页接口fetchNext - 流处理逻辑中区分事件类型,分别走新搜索请求和下一页分页请求
完整修改后代码
import 'dart:async'; import 'package:gifs/resources/tenor_api.dart'; import 'package:tenor/tenor.dart'; import 'package:rxdart/rxdart.dart'; // 定义操作事件类型 abstract class SearchEvent {} // 新搜索事件,携带搜索词 class SearchNewQueryEvent extends SearchEvent { final String query; SearchNewQueryEvent(this.query); } // 加载下一页事件 class SearchLoadNextPageEvent extends SearchEvent {} class SearchResult { final _api = TenorApi().api; Stream<TenorResponse> _res; Stream<TenorResponse> get res => _res; final _searchEvents = PublishSubject<SearchEvent>(); // 对外暴露的新搜索方法 void searchTerm(String query) => _searchEvents.add(SearchNewQueryEvent(query)); // 对外暴露的加载下一页方法 void loadNextPage() => _searchEvents.add(SearchLoadNextPageEvent()); // 存储状态:上一次的搜索词、上一次的返回结果 String? _lastValidQuery; TenorResponse? _lastResponse; SearchResult() { _res = _searchEvents .debounce((event) { // 仅新搜索做防抖,加载下一页不需要防抖 if (event is SearchNewQueryEvent) { return TimerStream(true, const Duration(milliseconds: 250)); } return TimerStream(true, Duration.zero); }) .switchMap((event) async* { if (event is SearchNewQueryEvent) { // 新搜索逻辑 final query = event.query.trim(); if (query.isEmpty) return; _lastValidQuery = query; final response = await _api.searchGIF(query, limit: 10); _lastResponse = response; yield response; } else if (event is SearchLoadNextPageEvent) { // 加载下一页逻辑:判断是否有历史搜索词和上一页结果 if (_lastValidQuery == null || _lastResponse == null) return; final nextResponse = await _lastResponse?.fetchNext(limit: 10); if (nextResponse != null) { _lastResponse = nextResponse; yield nextResponse; } } }); } void dispose() { _searchEvents.close(); } }
使用方式
- 触发新搜索时直接调用
searchTerm("搜索词")即可,和原有逻辑兼容 - 需要加载同关键词下一页时,调用
loadNextPage()即可,会自动校验当前是否有可加载的分页数据,返回下一页结果
内容的提问来源于stack exchange,提问作者Randomize
相关产品推荐
相关产品推荐

