계정 정보 다이얼로그 추가 및 전체 목록 페치 개선
This commit is contained in:
65
lib/core/common/utils/pagination_utils.dart
Normal file
65
lib/core/common/utils/pagination_utils.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
import '../models/paginated_result.dart';
|
||||
|
||||
/// 페이지네이션 API에서 모든 항목을 수집하는 도우미.
|
||||
///
|
||||
/// - 백엔드가 기본적으로 페이지 크기 제한을 두는 경우, 반복 호출로 전체 목록을 확보한다.
|
||||
/// - `maxPages`는 안전장치로 사용하며, 비정상 응답으로 무한 루프에 빠지는 것을 막는다.
|
||||
typedef PaginatedRequest<T> =
|
||||
Future<PaginatedResult<T>> Function(int page, int pageSize);
|
||||
|
||||
/// 페이지 단위로 제공되는 데이터를 모두 불러온다.
|
||||
///
|
||||
/// - [request]는 페이지 번호와 페이지 크기를 받아 `PaginatedResult`를 반환해야 한다.
|
||||
/// - [pageSize]는 첫 호출에 사용할 기본 페이지 크기이며, 서버가 다른 값을 돌려주면
|
||||
/// 이후 호출에서는 응답 값을 따른다.
|
||||
/// - [maxPages]는 허용할 최대 페이지 수로, 비정상 응답을 대비한 제한값이다.
|
||||
Future<List<T>> fetchAllPaginatedItems<T>({
|
||||
required PaginatedRequest<T> request,
|
||||
int pageSize = 100,
|
||||
int maxPages = 50,
|
||||
}) async {
|
||||
final results = <T>[];
|
||||
var currentPage = 1;
|
||||
var pagesFetched = 0;
|
||||
var effectivePageSize = pageSize > 0 ? pageSize : 100;
|
||||
|
||||
while (pagesFetched < maxPages) {
|
||||
final previousLength = results.length;
|
||||
final response = await request(currentPage, effectivePageSize);
|
||||
pagesFetched += 1;
|
||||
|
||||
final items = response.items;
|
||||
if (items.isEmpty) {
|
||||
break;
|
||||
}
|
||||
|
||||
results.addAll(items);
|
||||
final added = results.length - previousLength;
|
||||
|
||||
if (added <= 0) {
|
||||
// 새 항목을 받지 못했다면 더 이상 진행하지 않는다.
|
||||
break;
|
||||
}
|
||||
|
||||
final receivedPageSize = () {
|
||||
if (response.pageSize > 0) {
|
||||
return response.pageSize;
|
||||
}
|
||||
if (items.isNotEmpty) {
|
||||
return items.length;
|
||||
}
|
||||
return effectivePageSize;
|
||||
}();
|
||||
|
||||
if (items.length < receivedPageSize) {
|
||||
// 마지막 페이지에 도달한 경우 즉시 종료한다.
|
||||
break;
|
||||
}
|
||||
|
||||
effectivePageSize = receivedPageSize;
|
||||
final nextPage = response.page > 0 ? response.page + 1 : currentPage + 1;
|
||||
currentPage = nextPage > currentPage ? nextPage : currentPage + 1;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
Reference in New Issue
Block a user