在很多中后台系统中很多页面都有列表数据 导出 excel 的需求,有时候是知道列表的总条数,有时候不知道,因此个人写了两个函数,用于获取列表的所有数据.
import chunk from 'lodash/chunk'
// 知道总条数
export default async (records, func, params = {}) => {
const allList = []
const allRes = []
const { pageSize = 50 } = params
let promises = []
for (let i = 1; i < Math.ceil(+records / pageSize) + 1; i++) {
promises.push(func({ ...params, pageNum: i, pageSize }))
const flag = i % 5
// pages > 5 就每次请求5页,请求完了在请求之后的数据
if (!flag) {
const res = await Promise.all(promises)
allRes.push(...res)
promises = []
}
// pages < 5 的情况
if (Math.ceil(+records / pageSize) + 1 <= 5) {
const res = await Promise.all(promises)
allRes.push(...res)
promises = []
}
// 确保最后的结尾数据都能收集到
if (i === Math.ceil(+records / pageSize)) {
const res = await Promise.all(promises)
allRes.push(...res)
promises = []
}
}
allRes.forEach(e => {
if (e instanceof Array) {
allList.push(...e)
}
if (e instanceof Object && e.data instanceof Array) {
allList.push(...e.data)
}
})
return allList
}
// 不知道总条数
export async function fetchAllPageWithoutTotal({
api,
params = {},
chunkSize = 50,
concurrent = 5
} = {}) {
const { pages = 1, data = [] } = await api({ ...params, pageNum: 1, pageSize: chunkSize })
if (pages <= 1) return data
const promises = []
for (let i = 2; i <= pages; i++) {
promises.push(
(pageNum => () =>
api({
...params,
pageNum,
pageSize: chunkSize
}))(i)
)
}
const allList = data
const chunkPromises = chunk(promises, concurrent)
for (let i = 0; i < chunkPromises.length; i++) {
const res = await Promise.all(chunkPromises[i].map(fn => fn()))
res.forEach(e => {
if (Array.isArray(e)) {
allList.push(...e)
}
if (e instanceof Object && Array.isArray(e.data)) {
allList.push(...e.data)
}
})
}
return allList
}