如何控制Promise回调顺序?实现API请求结果按原序存储
如何保证Promise请求结果按原始顺序存入数组
问题原因
你的代码中,axios请求是异步操作,不同请求的完成时间不确定,直接push到数组会导致结果顺序和items的原始顺序不一致;另外代码存在变量名不统一(定义了results_arr却使用arr)、var循环的变量提升问题,这些都会影响最终结果。
解决方案
方法一:利用Promise.all的返回顺序特性
Promise.all会严格按照传入的promise数组的顺序,返回对应的结果数组,不需要手动维护顺序。只需让每个promise最终resolve为请求结果即可:
var results_arr = []; var promises = []; for (var i = 0 ; i < items.length;i++){ var url = `/api/stat/${items[i].id}`; // 让每个promise最终resolve为请求结果res promises.push(axios.get(url).then(res => res)); } Promise.all(promises).then(function(values) { results_arr = values; // values就是按items原始顺序排列的结果数组 console.log("finishpromise", results_arr); });
方法二:通过索引直接定位数组位置
如果需要在每个请求完成时就将结果放到对应位置(比如需要实时填充数组),可以初始化对应长度的数组,利用循环索引将结果存入指定位置。注意要使用let声明循环变量(避免var的变量提升问题):
var results_arr = new Array(items.length); // 初始化与items长度一致的数组 var promises = []; for (let i = 0 ; i < items.length;i++){ // let保证每个循环迭代有独立的i变量 var url = `/api/stat/${items[i].id}`; promises.push( axios.get(url).then(res=>{ results_arr[i] = res; // 将结果存入对应索引的位置 }) ); } Promise.all(promises).then(function() { console.log("finishpromise", results_arr); });
补充说明
- 方法一代码更简洁,是最常用的方式;方法二更适合需要实时跟踪每个请求结果位置的场景。
- 原代码中的变量名不一致问题(
results_arr和arr)需要修正,避免报错。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

