我的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代码无法成功加载文本文件并因此给我一些无序输出而造成的,但这只是我的观点,这是新手“程序员”的观点...
请帮助我!
杰里
答案 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
答案 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);