我正在尝试在for循环中发送多个AJAX请求。我需要确保响应与正在进行的正确请求相关联。我正在关注此处发布的解决方案XMLHttpRequest in for loop 这里,fileBatches是循环的大小。我正在尝试捕获响应,该响应表示有关请求数量成功和失败的信息,并尝试将其存储在_finalResponseArray中。如果fileBatches的长度为3,则第一个请求可能比其他请求花费更多时间。考虑第一个请求,需要一些时间来处理,到时候,第二个请求和第三个请求将完成,然后第一个请求将完成。我需要确保正确的请求与正确的响应相关联。这里,当第一个循环开始(i = 0)时,需要一些时间来处理,并且在第二个循环开始(i = 1)时进行处理。 XHR [i] .readyState == 4(因为我增加1并且如何获得i = 0的值?)变得混乱,我无法将响应链接到正确的请求。请在下面找到代码。下面的函数被执行多个AJAX请求。
var XHR = [];
var fileBatches = "Calling a function which returns array of values that needs to be processed"
var _finalResponseArray = [];
for (var i = 0; i < fileBatches.length; i++)
{
(function(i)
{
finalBatch = []
finalBatch.push("Things that need to be processed by controller");
finalData = finalBatch.join('&').replace(/%20/g, '+'); // Sending the values in a format so that it will be received by controller
XHR[i] = new XMLHttpRequest();
console.log(i);
XHR[i].open('POST', theURL);
XHR[i].onreadystatechange = function (event)
{
console.log("Here");
if (XHR[i].readyState == 4)
{
console.log("This request is complete");
console.log("I value is " + i);
if (XHR[i].status == 200)
{
_finalResponseArray.push(XHR[i].responseText);
console.log("Inside" + _finalResponseArray);
}
}
}
XHR[i].setRequestHeader('accept', 'text/JSON');
XHR[i].send(finalData);
})(i);
}
我不确定我在这里做错了什么,但请求没有与正确的响应相关联,而是随机添加到_finalResponseArray。如果只有一个请求没有任何循环,它可以完美地工作。如何确保onreadystatechange被验证是否正确循环?
**********更新
按照评论和其他各种方法(在堆栈溢出中引用过去的问题)中的建议尝试了解决方案:
即使我尝试使用闭包,反应也会变得混乱。对于所有3个请求,它会随机选择一个响应并为所有3个请求生成相同的响应。
我的请求是否应该有独特的内容,以便响应可以正确跟踪它。当我们尝试发送ant GET或POST请求时,我确实看到迭代器值'i'被附加到URL,但我只是为不同的请求发送相同的URL。那有关系吗?
答案 0 :(得分:2)
首先,我建议使用所谓的#!
- 而不是繁琐的onreadystatechange内容,只需使用XMLHttpRequest 2.0
和onload
(您将在下面的代码中看到后者的原因) )
由于onloadend
的异步性质,您无法预测请求何时全部完成,因此XMLHttpRequest
只有在最终_finalResponseArray
完成后才会完成
添加完整请求数将允许您在所有请求完成后在onloadend
回调中执行所需操作。无论成功与否,都会调用onloadend
我也使用onloadend
代替IIFE
.forEach
答案 1 :(得分:1)
您可能希望将onreadystatechange函数逻辑拉入其自己的函数定义中,以便它可以在本地管理范围。试试这个:
var XHR = [];
var _finalResponseArray = [];
var createReadyStateChangeCb = function(responseIdx)
{
return function(event)
{
console.log("Here");
if (XHR[responseIdx].readyState == 4)
{
console.log("This request is complete");
console.log("I value is " + responseIdx);
if (XHR[responseIdx].status == 200)
{
_finalResponseArray.push(XHR[responseIdx].responseText);
console.log("Inside" + _finalResponseArray);
}
}
}
}
for (var i = 0; i < fileBatches.length; i++)
{
(function(i)
{
finalBatch = []
finalBatch.push("Things that need to be processed by controller");
finalData = finalBatch.join('&').replace(/%20/g, '+'); // Sending the values in a format so that it will be received by controller
XHR[i] = new XMLHttpRequest();
console.log(i);
XHR[i].open('POST', theURL);
XHR[i].onreadystatechange = createReadyStateChangeCb(i);
}
XHR[i].setRequestHeader('accept', 'text/JSON');
XHR[i].send(finalData);
})(i);
}