JavaScript中数组间歇性加载不同数量对象的问题求助
问题分析与解决方案
看起来你遇到的是异步请求的时序问题,因为$.ajax默认是异步执行的,$.each会同步遍历AdditionalUrls并立刻发起两个请求,但这两个请求的完成时间是不确定的——可能第二个请求还没返回,你就去使用macArray了,所以会看到数组只加载了部分内容。另外你的代码里还有个小问题:currObj = this没有声明变量,会变成全局变量,虽然这里没用到,但也是潜在的bug。
问题根源拆解
$.each是同步循环,会快速发起两个AJAX请求,但请求的响应是异步返回的,谁先回来谁先往macArray里推数据。- 如果在所有请求完成前就访问
macArray(比如后续有依赖这个数组的操作),就会得到不完整的结果。 - 未声明的
currObj变量会污染全局作用域,虽然当前代码没用到,但后续如果不小心引用会出问题。
修复方案:用Promise.all确保所有请求完成
我们可以把每个AJAX请求包装成Promise,然后用Promise.all等待所有请求完成后再统一处理数据,这样就能保证macArray是完整的:
var macArray = []; $(document).ready(function() { loadMac(); }); function loadMac() { var AdditionalUrls = ['/_vti_bin/ListData.svc/MACCalendar','/_vti_bin/ListData.svc/QlarantCalendar']; // 把每个AJAX请求转成Promise var requestPromises = AdditionalUrls.map(function(url) { return new Promise(function(resolve, reject) { $.ajax({ url: url, type: "GET", data: { $select: "title" }, headers: { accept: "application/json;odata=verbose" }, success: function(data) { resolve(data.d.results); // 把请求结果传给Promise }, error: function(err) { reject(err); // 处理错误 } }); }); }); // 等待所有请求完成 Promise.all(requestPromises) .then(function(allResults) { // 遍历所有请求的结果,合并到macArray allResults.forEach(function(results) { results.forEach(function(item) { macArray.push({ title: item.title }); }); }); // 这里可以放心使用完整的macArray了 console.log("完整的macArray:", macArray); }) .catch(function(error) { console.error("请求出错:", error); }); }
额外的优化点
- 用
let/const代替全局变量:如果macArray不需要全局,可以把它放在loadMac函数内部,避免全局污染。 - 修复变量声明:如果确实需要
currObj,要加上let currObj = this,确保它在当前循环的作用域内。 - 错误处理:原来的代码没有处理AJAX失败的情况,加上
error回调和Promise的catch可以避免静默失败。
另一种方案:使用async/await(更简洁)
如果你环境支持ES6+,可以用async/await让代码更像同步写法,逻辑更清晰:
$(document).ready(function() { loadMac(); }); async function loadMac() { const AdditionalUrls = ['/_vti_bin/ListData.svc/MACCalendar','/_vti_bin/ListData.svc/QlarantCalendar']; const macArray = []; try { for (const url of AdditionalUrls) { const data = await $.ajax({ url: url, type: "GET", data: { $select: "title" }, headers: { accept: "application/json;odata=verbose" } }); data.d.results.forEach(item => { macArray.push({ title: item.title }); }); } // 所有请求完成,macArray已完整 console.log("完整的macArray:", macArray); } catch (error) { console.error("请求出错:", error); } }
内容的提问来源于stack exchange,提问作者Dylan
相关产品推荐
相关产品推荐

