Express NodeJS API浏览器刷新导致分页结果数组为空问题
结论
这个现象不属于正常行为,是分页中间件的代码逻辑错误导致的。
问题根因
- 误用数组
splice()方法破坏原始数据源Array.prototype.splice是原地修改数组的方法,执行后会直接删除原数组的指定元素。你的代码中projects变量是模块加载时就初始化的全局引用,每次接口请求执行splice都会直接删掉原始数组里的对应数据:
第一次请求默认page=1时,删除前10条,原数组剩余19条;第二次刷新再请求page=1,又从剩余数组里删除前10条,原数组仅剩9条;第三次请求时数组已经没有足够元素可返回,自然得到空的results数组。
另外splice的第二个参数代表要删除的元素数量,你传入endIndex(即page*limit)本身参数传参就不符合API要求,分页截取逻辑从根源上就是错的。 - 总页数计算逻辑错误
你用Math.round(config.modelSize / limit)计算总页数存在边界问题:当总条数除以limit的小数部分小于0.5时,会向下取整导致少算一页。比如总共有24条数据、每页10条时,计算结果为2,但实际需要3页才能展示完所有数据。
修复代码
把splice替换为不会修改原数组的slice方法(slice的两个参数恰好就是截取的起始索引、结束索引,和你定义的startIndex/endIndex逻辑完全匹配),同时把总页数计算改为Math.ceil向上取整:
function paginate(model) { return async (req, res, next) => { const page = parseInt(req.query.page) || config.startingPage; const limit = parseInt(req.query.limit) || config.limitDefault; const startIndex = (page - 1) * limit; const endIndex = page * limit; // 修复总页数计算 const numOfPages = Math.ceil(config.modelSize / limit); const result = {}; if (endIndex < model.length) { result.next = { page: page + 1, limit: limit, }; } if (startIndex > 0) { result.previous = { page: page - 1, limit: limit, }; } try { result.collectionSize = config.modelSize; result.numOfPages = numOfPages; // 修复:用slice做数据截取,不修改原数组,参数匹配截取规则 result.results = model.slice(startIndex, endIndex); res.paginatedResult = result; return next(); } catch (e) { res.status(500).json({ message: e.message }); } }; }
修复后无论刷新多少次接口,只要传入的分页参数不变,返回结果都会保持一致,不会再出现数据逐次减少最终为空的问题。
内容的提问来源于stack exchange,提问作者user2668392
相关产品推荐
相关产品推荐

