You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Promise处理分页REST API的状态码作用域与数组扁平化问题咨询

分页API全量数据获取的问题修复方案

原代码的核心问题

  1. 异步循环控制失效:do-while是同步循环,发起请求后立刻判断循环条件,但此时API请求还没完成,statusCode根本没被异步回调修改,导致循环无法正确判断是否需要继续请求下一页。
  2. 返回二维数组:收集所有请求的Promise后用Promise.all()返回,每个Promise对应一页的workers数组,最终结果自然是二维的,需要额外调用flat()处理。

修复后的完整代码

exports.get_workers = async (access_token, certificate, private_key) => {
    let page = 0;
    const pageSize = 2;
    const allWorkers = [];

    while (true) {
        try {
            const workersPage = await new Promise((resolve, reject) => {
                const options = {
                    hostname: 'accounts.adp.com',
                    path: `/hr/v2/workers?$top=${pageSize}&$skip=${page * pageSize}`,
                    method: 'GET',
                    headers: {
                        'Accept': 'application/json;masked=false',
                        'Authorization': `Bearer ${access_token}`
                    },
                    cert: certificate,
                    key: private_key,
                };

                const req = require('https').request(options, (res) => {
                    // 处理错误状态码(除了204)
                    if (res.statusCode < 200 || (res.statusCode >= 300 && res.statusCode !== 204)) {
                        reject(new Error(`请求失败: HTTP ${res.statusCode}`));
                        return;
                    }

                    // 204代表无更多数据,返回空数组终止循环
                    if (res.statusCode === 204) {
                        resolve([]);
                        return;
                    }

                    const body = [];
                    res.on('data', chunk => body.push(chunk));
                    res.on('end', () => {
                        const parsedData = JSON.parse(Buffer.concat(body).toString());
                        resolve(parsedData.workers);
                    });
                });

                req.on('error', err => reject(`网络错误: ${err.message}`));
                req.end();
            });

            // 无数据则退出循环
            if (workersPage.length === 0) break;

            // 合并当前页数据到总数组(一维)
            allWorkers.push(...workersPage);
            page++;
        } catch (err) {
            throw new Error(`获取第${page}页数据失败: ${err}`);
        }
    }

    return allWorkers;
};

关键修复点说明

1. 解决异步循环的状态码判断问题

  • 改用异步while循环,通过await等待每一页请求完成后,再处理下一页。这样能确保我们拿到当前请求的真实状态,判断是否还有后续数据。
  • 把状态码的处理逻辑直接放到Promise内部:如果返回204,就resolve空数组,外部循环检测到空数组就终止;其他错误状态直接抛出异常,避免无效循环。
  • 彻底抛弃了依赖外部变量传递状态码的方式,从根源上解决异步同步不匹配的问题。

2. 直接返回一维数组

  • 初始化一个总数组allWorkers,每拿到一页的workers数据,用扩展运算符...把单页的每个元素直接追加到总数组里(allWorkers.push(...workersPage)),这样总数组始终是一维结构。
  • 函数最终直接返回这个总数组,调用方不需要再做flat()处理。

内容的提问来源于stack exchange,提问作者craig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:22:45