为何使用jQuery each循环时返回值顺序不一致?
为什么each循环遍历后返回内容顺序不一致?
你的问题其实不是each循环的遍历顺序错了,而是AJAX请求的异步特性导致回调执行顺序不确定!
问题根源拆解
你用$(month).each遍历数组的时候,确实是严格按照January到December的顺序发起AJAX请求的,但AJAX是异步操作——每个请求的响应时间可能不一样(比如服务器处理某个月份的逻辑更耗时、网络波动等),哪个请求先拿到响应,它的回调函数就会先执行,所以最终生成的<tr>会按响应完成的顺序插入,而非你遍历数组的顺序。
解决方案
这里推荐两种靠谱的处理方式,优先选第二种(效率更高):
方案1:串行发起请求(一个完成再发下一个)
这种方式会严格保证顺序,但总耗时是所有请求的时间之和:
var selectedYear = <?= json_encode($selectedYear) ?>; var months = <?= json_encode($months) ?>; // 用递归实现串行请求 function fetchMonth(index) { if (index >= months.length) return; // 遍历结束 $.ajax({ type: 'POST', url: 'scripts/ajax-mon...', data: { year: selectedYear, month: months[index] }, success: function(response) { // 按顺序插入到表格 $('table').append(response); // 假设response是生成好的<tr> fetchMonth(index + 1); // 发起下一个请求 } }); } // 启动第一个请求 fetchMonth(0);
方案2:并行请求+按原顺序渲染(推荐)
所有请求同时发起,等全部完成后,再按照原数组的顺序把结果插入DOM,既保证顺序又不浪费时间:
var selectedYear = <?= json_encode($selectedYear) ?>; var months = <?= json_encode($months) ?>; // 生成所有AJAX请求的Promise数组 var requestPromises = months.map(function(month, index) { return new Promise(function(resolve, reject) { $.ajax({ type: 'POST', url: 'scripts/ajax-mon...', data: { year: selectedYear, month: month }, success: function(response) { // 保存索引和响应内容,方便后续排序 resolve({ index: index, html: response }); }, error: function(err) { reject(err); } }); }); }); // 等待所有请求完成 Promise.all(requestPromises) .then(function(results) { // 按索引排序,保证原顺序 results.sort(function(a, b) { return a.index - b.index; }); // 依次插入DOM results.forEach(function(item) { $('table').append(item.html); }); }) .catch(function(err) { console.error('请求出错:', err); });
额外提醒
- 尽量避免用
async: false设置同步AJAX,这会阻塞浏览器主线程,导致页面卡顿,用户体验极差。 - 如果后端允许,也可以改成一次请求获取所有月份的数据,这样根本不需要循环发起AJAX,既减少服务器压力,又彻底避免顺序问题,这是最优解!
内容的提问来源于stack exchange,提问作者Kafus
相关产品推荐
相关产品推荐

