Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果循环中有多个AJAX请求,如何将XMLHTTP请求链接到正确的响应_Javascript_Ajax_Asynchronous_Xmlhttprequest - Fatal编程技术网

Javascript 如果循环中有多个AJAX请求,如何将XMLHTTP请求链接到正确的响应

Javascript 如果循环中有多个AJAX请求,如何将XMLHTTP请求链接到正确的响应,javascript,ajax,asynchronous,xmlhttprequest,Javascript,Ajax,Asynchronous,Xmlhttprequest,我试图在for循环中发送多个AJAX请求。我需要确保响应与提出的正确请求相关联。我正在遵循发布在这里的解决方案 这里,fileBatches是循环的大小。我正试图捕获表示成功和失败请求数量的信息的响应,并试图将其存储在_finalResponseArray中。如果FileBatchs的长度为3,则第一个请求可能比其他请求花费更多的时间。考虑第一个请求,花一些时间来处理,并且在时间上,第二个请求和第三个请求将完成,然后第一个请求将完成。我需要确保正确的请求与正确的响应相关联。这里,当第一个循环开始

我试图在for循环中发送多个AJAX请求。我需要确保响应与提出的正确请求相关联。我正在遵循发布在这里的解决方案 这里,fileBatches是循环的大小。我正试图捕获表示成功和失败请求数量的信息的响应,并试图将其存储在_finalResponseArray中。如果FileBatchs的长度为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);
}
var XHR=[];
var fileBatches=“调用返回需要处理的值数组的函数”
var _finalResponseArray=[];
对于(var i=0;i
我不确定我在这里做错了什么,但请求没有链接到正确的响应,它们随机添加到_finalResponseArray。如果只有一个请求而没有任何循环,那么它可以完美地工作。如何确保onreadystatechange被验证为正确的循环

**********更新

根据评论和其他各种方法(参考堆栈溢出中过去的问题)中的建议,尝试了解决方案:

即使我尝试使用闭包,响应也会出错。对于所有3个请求,它随机选择一个响应,并为所有3个请求生成相同的响应


我的请求是否应该具有唯一性,以便响应能够正确跟踪它。当我们尝试发送ant GET或POST请求时,我确实看到迭代器值“I”被附加到URL,但我只是为不同的请求发送相同的URL。那有关系吗

您可能希望将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);
}
var XHR=[];
var _finalResponseArray=[];
var createReadyStateCb=函数(响应ID)
{
返回函数(事件)
{
console.log(“此处”);
if(XHR[responseIdx].readyState==4)
{              
console.log(“此请求已完成”);
log(“I值为”+responseIdx);
if(XHR[responseIdx].status==200)
{
_最终响应array.push(XHR[responseIdx].responseText);
console.log(“内部”+_finalResponseArray);
}
}
}
}
对于(var i=0;i
首先,我建议使用所谓的
XMLHttpRequest 2.0
——而不是那些烦琐的onreadystatechange东西,只需使用
onload
onloadend
(下面的代码中可以看到后者的原因)

由于
XMLHttpRequest
的异步性质,您无法预测请求何时全部完成,因此
\u finalResponseArray
只有在最终的
onloadend
完成后才会完成

添加完整请求的计数将允许您在所有请求完成后在
onloadend
回调中执行所需的任何操作。无论成功或失败,都会调用onloadend

我还使用
.forEach
而不是iLife

var fileBatches = "Calling a function which returns array of values that needs to be processed"
var _done = 0;
var _count = fileBatches.length;
var _finalResponseArray = [];

fileBatches.forEach(function(item, i) {
    var finalBatch = []
    var xhr = new XMLHttpRequest();
    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.open('POST', theURL);
    xhr.onload = function (event) {
        if (xhr.status == 200) {
            _finalResponseArray[i] = (xhr.responseText);
        }         
    };
    xhr.onloadend = function (event) {
        // this gets called in ALL cases, i.e. after load, error or abort
        if(++_done == _count) {
            // _finalResponseArray is complete here
        }
    };
    xhr.setRequestHeader('accept', 'text/JSON');
    xhr.send(finalData);
});
//_finalResponseArray will ALWAYS be empty here

您的缩进使代码无法读取可能
finalBatch
不在您发布的代码中-每个循环都会立即将其删除-您可能也不需要
XHR
数组,因为为什么需要访问循环外的所有XHR?因为
XMLHttpRequest
是异步的,所以不能保证它们将以什么顺序完成,所以也不能保证结果将以什么顺序推送到结果数组上-尝试使用
\u finalResponseArray[i]=XHR.responseText
如果您需要正确的顺序-请注意,如果某些请求失败,finalResponseArray可能会有空插槽,而且,同样,由于XHR的异步性质,无法知道(使用当前代码)何时所有请求都被删除