在开发小程序时,我们经常需要从数据源获取所有数据。然而,微搭的限制是每次只能最多获取 200 条记录,这对我们的业务需求并不符合。

为了解决这个问题,我们可以实现分页机制,以便获取全部数据。以下是具体的实现思路和代码示例。

代码实现

const allImportData = []; // 用于存储所有导入数据
const pageSize = 200; // 每页最多200条记录
let pageNumber = 1; // 当前页码

// 首先获取初始数据,以确定总记录数
const initialResponse = await context.callModel({
    name: 'dcdr', // 数据源标识
    methodName: 'wedaGetRecordsV2', // 方法标识
    params: {
        orderBy: [{ createdAt: "desc" }], // 按创建时间倒序排序
        select: { $master: true }, // 返回主表字段
        getCount: true, // 请求总记录数
        pageSize: pageSize, // 每页记录条数
        pageNumber: pageNumber, // 当前页码
        compatibleWithV1: true // 兼容性设置
    }
});

// 将第一页的数据存入数组中
allImportData.push(...initialResponse.records);

// 获取总记录数和总页数
const totalRecords = initialResponse.total;
const totalPages = Math.ceil(totalRecords / pageSize); // 向上取整,确保页码正确

// 定义一个数组,用于存储后续页的请求
const fetchPromises = [];

// 异步请求后续页的数据
for (let i = 2; i <= totalPages; i++) {
    fetchPromises.push(
        context.callModel({
            name: 'dcdr',
            methodName: 'wedaGetRecordsV2',
            params: {
                orderBy: [{ createdAt: "desc" }],
                select: { $master: true },
                getCount: false, // 不需要再次获取总数
                pageSize: pageSize,
                pageNumber: i,
                compatibleWithV1: true
            }
        }).then(response => response.records) // 处理响应数据
    );
}

// 使用 Promise.all 并行执行所有请求,并收集返回的数据
const pagesData = await Promise.all(fetchPromises);
pagesData.forEach(pageRecords => allImportData.push(...pageRecords)); // 将后续页的数据添加到总数组中

代码解析

我们拆解一下思路,首先我们定义了每页的显示条数和页码

1. 定义参数

const pageSize = 200;
let pageNumber = 1;

这里我们总是每次取200条符合他的API的要求,然后页面从第一页开始获取

因为最终返回的数据是一个数组,所以我们定义一个变量用来存储从数据源读取到的数据

const allImportData = [];

2. 获取初始数据

接着我们就先调用获取多条的方法,查询一下第一页的数据

const initialResponse = await context.callModel({
        name: 'dcdr',
        methodName: 'wedaGetRecordsV2',
        params: {
            orderBy: [{ createdAt: "desc" }],
            select: { $master: true },
            getCount: true,
            pageSize: pageSize,
            pageNumber: pageNumber,
            compatibleWithV1: true
        }
    });

这里name就是我们数据源的标识,methodName是我们的方法标识。

params是我们方法调用的入参,这里orderBy是排序字段,select是返回的字段,$master:true表示返回全部字段。

getCount表示返回总记录条数,在返回的结果里是通过total属性体现。

pageSize是每页的返回数据条数,pageNumber表示第几页,compatibleWithV1: true这个表示要返回关联关系主表的字段,如果你的表的字段设置了关联关系这个才起作用

allImportData.push(...initialResponse.records);

这一行的代码的意思是把我们查询到的第一页的数据存入数组中,数组如果需要存入数据的可以调用push方法存入

括号里边我们用了展开的语法,这样就会把第一页的数据全部展开存入,这种类似于我们自己实现用循环的语法

for (let record of initialResponse.records) {
    allImportData.push(record);
}

3. 计算总记录和总页数

接着我们返回记录总条数,并且记录总页数

 const totalRecords = initialResponse.total;

    // Calculate total pages based on pageSize and totalRecords
    const totalPages = Math.ceil(totalRecords / pageSize);

这里我们用了Math.ceil方法,这个表示向上取整,比如我们计算是5.2页,那么上取整就变成了6页。因为到了最后一页有可能会少于200条,这样处理保证我们的页码是正确的

4. 并行请求后续页的数据

接着我们定义了一个数组用来异步加载后续的数据

const fetchPromises = [];

如果你直接用await的语法等待每页返回,云函数就会超时报错,我们使用异步执行,这样可以节约时间

for (let i = 2; i <= totalPages; i++) {
        fetchPromises.push(
            context.callModel({
                name: 'dcdr',
                methodName: 'wedaGetRecordsV2',
                params: {
                    orderBy: [{ createdAt: "desc" }],
                    select: { $master: true },
                    getCount: false,
                    pageSize: pageSize,
                    pageNumber: i,
                    compatibleWithV1: true
                }
            }).then(response => response.records)
        );
    }

    // Await and collect all pages' records
    const pagesData = await Promise.all(fetchPromises);

最后这一部分就是去组装我的查询,每次循环都放入数组中,用Promise.all去并行的执行

5. 收集所有数据

在所有请求完成后,通过 forEach 将返回的数据合并到 allImportData 中

pagesData.forEach(pageRecords => allImportData.push(...pageRecords));

forEach 是一个数组的方法,用于遍历数组中的每个元素。

在每次循环时,都会调用小括号内的箭头函数。箭头函数是一种简洁的函数写法,左侧是传入的参数(在这里是 pageRecords),右侧是具体的执行逻辑。

在这个例子中,我们提取出当前元素(一个数组),并使用展开语法(…)将它的所有元素添加到最终结果数组 allImportData 中。

总结

通过以上方法,我们成功地实现了对数据源的全部数据进行分页获取。这种做法不仅提高了数据请求的效率,还确保了我们可以灵活地处理大量数据。希望这个技术分享能对您在使用微搭开发小程序时有所帮助!

Logo

低代码爱好者的网上家园

更多推荐