如何保证分页异步HTTP请求的返回结果按调用顺序处理?
解决方案
你遇到的问题本质是异步HTTP请求的返回顺序不受发起顺序控制,针对分页场景有3种常用的修复方案:
方案1:按页码占位存储(推荐,兼顾性能和顺序)
不要直接把返回结果push到全局数组,而是给每个请求绑定对应页码,返回后直接写入数组对应下标位置,不管请求返回顺序如何,最终数据位置都是正确的。该方案也适配无限滚动的懒加载场景,不需要提前知道总页数,每次触发新页请求时传入对应页码即可。
修改后的代码示例:
// 全局存储数组,按页存储数据,不需要提前指定长度 this.pageData = [] getData() { // 给每个请求传递对应的页码 this.lazyLoadData(1, this.testing.bind(this)); this.lazyLoadData(2, this.testing.bind(this)); this.lazyLoadData(3, this.testing.bind(this)); } lazyLoadData(pageNum, cb?) { // 发请求时带上页码参数 axios.get('/你的接口地址', { params: { page: pageNum, pageSize:25 } }) .then(res => { cb && cb(pageNum, res.data); }) } testing(pageNum, data) { // 直接把数据放到对应页码的位置,而不是push this.pageData[pageNum - 1] = data; // 过滤掉未返回的空占位,拍平后即可用于渲染 const fullRenderData = this.pageData.flat().filter(item => !!item); // 后续表格渲染逻辑 }
方案2:用Promise.all统一处理返回结果(适合提前知道所有要请求页码的场景)
把所有请求包装成Promise实例,用Promise.all等待全部请求完成,返回的结果顺序和你传入Promise的顺序完全一致,和请求返回快慢无关。
代码示例:
async getData() { // 按顺序构造所有请求的Promise数组 const requestPromiseList = [1,2,3,4].map(page => this.lazyLoadData(page)); // 所有请求完成后,result的顺序完全对应1、2、3、4页的顺序 const pageResultList = await Promise.all(requestPromiseList); // 直接拼接即可得到顺序正确的完整数据 const fullRenderData = pageResultList.flat(); // 后续表格渲染逻辑 } // 修改lazyLoadData返回Promise lazyLoadData(pageNum) { return axios.get('/你的接口地址', { params: { page: pageNum, pageSize:25 } }).then(res => res.data) }
方案3:串行发起请求(适合请求有前后依赖的场景)
必须等上一页请求完成再发下一页,天然保证返回顺序,缺点是请求总耗时会变长,不如并行请求高效。
代码示例:
async getData(totalPage = 4) { const fullRenderData = []; for(let page = 1; page <= totalPage; page++) { const pageData = await this.lazyLoadData(page); fullRenderData.push(pageData); } // 后续表格渲染逻辑 } lazyLoadData(pageNum) { return axios.get('/你的接口地址', { params: { page: pageNum, pageSize:25 } }).then(res => res.data) }
内容的提问来源于stack exchange,提问作者Petar
相关产品推荐
相关产品推荐

