什么是执行多个AJAX请求的正确方法,以便每个请求都在setInterval()内部?

时间:2018-08-06 09:30:24

标签: javascript ajax promise setinterval

我有一个2D数组,其中包含一堆数组,每个数组都包含一堆URL字符串(有关该URL的其他数据)。

我们将2D数组中的数组称为“ 外部数组”,然后将“ outer-arrays ”中的数组称为“ < em>内部数组”。

我需要遍历2D数组,对于其中包含的每个外部数组,我需要每隔10秒发送一次AJAX请求(10秒的间隔是可变的,因不同而异网址),并且这种情况将永远持续下去(除非用户停止它)。如果AJAX请求的响应成功,则UI上将发生某些事情,即,我将对DOM进行更改。

问题是我想同时异步发送所有这些AJAX请求(如果我正确理解该词的话)。

看下面的代码。它有一个循环。它的问题在于它有一个循环,在循环中有一个setInterval函数被调用。假设在循环的第一次迭代中,setInterval()将开始每10秒发送一次AJAX请求,但是由于setInterval()和AJAX是异步的,因此控件将继续进行到循环的第二次迭代,并且过程继续进行上。

我感觉自己的做法不正确。这里有些混乱。因此,请告诉我我是否做得正确,还是应该以其他方式完成?

for (var outerArray in big2DArray) {
  setInterval(function() {
    $.ajax({
        url: "...",
        method: "...",
        success: function(dataReturned, status, jqXHR) {
            alert("At this point we make some change in DOM");
        },
        error: function(jqXHR, status, exception) {
            alert("error");
        }
    });
   }, 60000);
}

1 个答案:

答案 0 :(得分:1)

如果要并行运行请求,我将始终确保在启动另一个请求之前已完成前一个请求,否则可能会发生,否则您创建的请求将超出连接能力。如果您之间的延迟足够大,那么您的代码就可以了,否则您可以这样做:

 const delay = ms => new Promise(res => setTimeout(res, ms));


 for (const outerArray of big2DArray) { // dont confuse for..of with for..in
  (async function() {
    while(true) {
      try {
        const result = await $.ajax({ // wait for the call to be done
          url: "...",
          method: "...",
        });
        // Work with result
     } catch(error) {
        // Handle connection errors
     }
     await delay(60000); // then wait for a slight delay before continuing
    }
   })();
 }

或者如果您想再次运行一个请求:

您要么像这样进行延迟循环:

 const delay = ms => new Promise(res => setTimeout(res, ms));

 (async function() {
   for (const outerArray of big2DArray) { // dont confuse for..of with for..in
    try {
       const result = await $.ajax({ // wait for the call to be done
          url: "...",
          method: "...",
       });
       // Work with result
    } catch(error) {
       // Handle connection errors
    }
    await delay(60000); // then wait for a slight delay before continuing
   }
 })();

或递归伪循环:

 (function next(index) { // entry point for recursive calls
    if(index >= outerArray.length) return;
    var outerArray = big2DArray[index];
    setTimeout(function() {
      $.ajax({
          url: "...",
          method: "...",
          success: function(dataReturned, status, jqXHR) {
             alert("At this point we make some change in DOM");
             next(i + 1); // continue with the next one
          },
          error: function(jqXHR, status, exception) {
              alert("error");
          }
      });
     }, 60000);
 })(0); // start with index = 0