检索GET请求时出现问题的响应顺序

时间:2018-07-25 23:00:49

标签: javascript jquery arrays asynchronous

我的JavaScript代码面临一些问题,因为我的理解可能与异步功能有关。

我有一些大的txt文件,我想在我的javascript代码中导入,所有文件都在同一域下。 例如,当我打开/index.php时,我希望Javascript从以下几个文本文件中加载文本:/log/ip_number/log.txt

此刻我正在使用这样的东西:

for (var i = 0; i < numberOfVPS; i++) {
    $.get("/log/"+ip_list[i]+"/log.txt", function(contents){
     //does my things with contents
     array.push(myOutput)
     });
}

在代码末尾,我应该得到一个按照ip_list数组中IP的顺序排序的数组....但是那不是我得到的,而且我真的不明白为什么...

例如,我应该得到: 数组= [1、2、3、4、5]

其中1、2、3、4和5与ip_list [0],ip_list [1],ip_list [2],ip_list [3],ip_list [4]相关, 但我得到类似的东西:

array = [2,5,3,1,4],并且每次我重新加载页面时,都会有不同的顺序。 我认为这是由于javascript代码无法成功加载文本文件并因此给我一些无序输出而造成的,但这只是我的观点,这是新手“程序员”的观点...

请帮助我!

杰里

3 个答案:

答案 0 :(得分:1)

一批GET请求并不总是按照触发顺序来解决。

您可以将.txt内容直接分配给其对应的键,而不是将结果推入数组。

array[i] = myOutput;

但是,由于GET回调中的i的值将不再与执行GET请求时的值相同(计数器在循环中不断增加),因此您需要生成一个新的作用域,其中该值i中的保留。一个function可以给我们。

您还需要一种方法来知道何时加载了最后一个文件...以执行操作...

let completed =0;

const getTxt = function(i){
  $.get("/log/"+ip_list[i]+"/log.txt", contents=>{
    array[i] = myOutput;
    completed++
    if(completed === numberOfVPS){ 
      // all files have been loaded 
      yourCallbackHere();
    }
  });
}

for(let i = 0; i < numberOfVPS; i++) getTxt(i)
  

我个人将使用Promises来实现这一点,它们是为了以更干净直观的方式处理异步操作。

答案 1 :(得分:1)

您的代码是异步的,因此您的选择之一就是使用Promise s 因此,例如,您可以将其编写为:

var files = [];
for( var n = 0; n < numberOfVPS; n++ ) {
   files[n] = $.get("FILEPATH");
}
$.when(...files).done(function(){
   array.push(...arguments);
});

https://api.jquery.com/jquery.when/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

https://davidwalsh.name/write-javascript-promises

答案 2 :(得分:0)

您的循环会进行异步调用以加载文件。该顺序将取决于回调函数何时已加载文件。这取决于文件的大小和网络延迟。

如果需要对数组中的项目进行排序,则可以在数组中存储一个对象,并在所有回调完成后对这些对象使用Array.prototype.sort()进行排序。

array.push({ index: i, ip: myOutput})

array.sort(function(a, b) {
  return a.index - b.index;
}

要获取原始数组,请使用Array.prototype.map();

array.map(x => x.ip);