fetchAllPaginatedData 函数文档

功能描述

fetchAllPaginatedData 是一个用于从分页 API 获取所有数据的工具函数。它会自动处理分页逻辑,将多个页面的结果合并成一个数组返回。

参数说明

必需参数

  • fetchFunction (Function): 用于获取数据的异步函数。该函数应接受一个参数对象并返回一个 Promise。

配置选项

  • params (Object, 默认值: {}): 请求的初始参数对象
  • pageSize (number, 默认值: 10): 每页的数据项数量
  • pageParamName (string, 默认值: 'pageNumber'): 请求参数中表示页码的字段名
  • totalCountParamName (string, 默认值: 'totalCount'): 响应数据中表示总数据量的字段名
  • dataParamName (string, 默认值: 'documents'): 响应数据中包含数据项数组的字段名
  • initialPage (number, 默认值: 1): 开始获取数据的初始页码

返回值

  • 返回一个 Promise,解析为包含所有获取到的数据项的数组

使用示例

import { fetchAllPaginatedData } from './paginationUtils';
 
// 定义获取函数
const fetchUsers = async (params) => {
  const response = await api.get('/users', { params });
  return response.data;
};
 
// 获取所有用户数据
const allUsers = await fetchAllPaginatedData(fetchUsers, {
  params: { active: true },
  pageSize: 20,
  pageParamName: 'page',
  totalCountParamName: 'total',
  dataParamName: 'items'
});

实现细节

  1. 函数首先获取初始页面的数据
  2. 根据响应中的总数据量和每页大小计算总页数
  3. 然后依次获取剩余页面的数据
  4. 将所有页面的数据合并后返回

注意事项

  • 确保 fetchFunction 返回的 Promise 解析值中包含指定的 totalCountParamNamedataParamName 字段
  • 函数会顺序获取所有页面,可能会产生多个网络请求

完整代码

/**
 * 从给定的获取函数中获取所有分页数据。
 *
 * 这个函数处理从分页 API 获取数据,将多个页面的结果合并成一个数组。
 *
 * @param {Function} fetchFunction - 用于获取数据的函数。它应该接受一个参数对象并返回一个 Promise。
 * @param {Object} options - 配置获取过程的选项。
 * @param {Object} [options.params={}] - 请求的初始参数。
 * @param {number} [options.pageSize=10] - 每页的数据项数量。
 * @param {string} [options.pageParamName='pageNumber'] - 请求中用于表示页码的参数名称。
 * @param {string} [options.totalCountParamName='totalCount'] - 响应中包含总数据量的字段名称。
 * @param {string} [options.dataParamName='documents'] - 响应中包含数据项数组的字段名称。
 * @param {number} [options.initialPage=1] - 开始获取数据的初始页码。
 * @returns {Promise<Array>} 一个 Promise,解析为包含所有获取到的数据项的数组。
 */
export const fetchAllPaginatedData = async (fetchFunction, {
  params = {},
  pageSize = 10,
  pageParamName = 'pageNumber',
  totalCountParamName = 'totalCount',
  dataParamName = 'documents',
  initialPage = 1
} = {}) => {
  let currentPage = initialPage;
  let totalCount = 0;
  let allDocuments = [];
 
  // 获取初始数据
  const initialParams = { ...params, [pageParamName]: currentPage, pageSize };
  const initialRes = await fetchFunction(initialParams);
 
  totalCount = initialRes[totalCountParamName] || 0;
  allDocuments = initialRes[dataParamName] || [];
 
  // 计算总页数
  const totalPages = Math.ceil(totalCount / pageSize);
 
  // 如果需要,获取更多页面的数据
  while (currentPage < totalPages) {
    currentPage += 1;
 
    const newParams = { ...params, [pageParamName]: currentPage, pageSize };
    const res = await fetchFunction(newParams);
 
    allDocuments = allDocuments.concat(res[dataParamName] || []);
  }
 
  return allDocuments;
};