如何使用Javascript/AJAX按特定顺序加载多个文件的内容



我正在使用JS/AJAX在页面上显示多个文件的内容。这些文件是动态生成的,并使用 for 循环加载。有一个文件包含该集的元数据,包括需要加载的其他文件数。其他文件的文件名中有一个数字,我通过请求"file_[loop_index].json"来加载它们。

问题是,每个 json 文件中的数据量也是任意的,AJAX 调用将按最小文件的顺序首先完成。我想根据名称而不是大小按顺序显示数据。

下面是一个精简的示例,假设我们要显示一本书的内容:

function get(url) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
resolve(req.response);
}
else {
reject(Error(req.statusText));
}
};
req.onerror = function() {
reject(Error("Network Error"));
};
req.send();
});
}
get('toc.json').then(function(response) {
chapters = JSON.parse(response)["chapters"];
return chapters;
}).then(function(levels) {
for (i = 0; i < chapters; i++) {
(function (i) {
get("chap".concat(i,".json")).then(function(response) {
console.log(response);
})
}(i));
}
});

目录.json:

{ "chapters": 2 }

第0章:

{ "text" : "00000" }

第1章:

{ "text" : "1" }

结果将是:

{ "text" : "1" }
{ "text" : "00000" }

就好像我要切换每个文件中的字符数一样,结果将是:

{ "text" : "0" }
{ "text" : "11111" }

我想在带有"0"的行之前打印带有"1"的行,无论每个文件大小如何。

我无法使用 async/await,因为我的页面必须在 IE11 中工作,并且它不支持箭头功能。

我想到的解决方案是将内容存储在一个数组中,从 for 循环中返回该内容,并显示内容,即:

尝试的解决方案:

var tempArray = [];
function get(url) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
resolve(req.response);
} else {
reject(Error(req.statusText));
}
};
req.onerror = function() {
reject(Error("Network Error"));
};
req.send();
});
}
get('toc.json').then(function(response) {
chapters = JSON.parse(response)["chapters"];
return chapters;
}).then(function(levels) {
for (i = 0; i < chapters; i++) {
(function(i) {
get("chap".concat(i, ".json")).then(function(response) {
console.log(response);
tempArray[i] = response;
})
}(i));
}
return tempArray;
}).then(function(response) {
console.log(response);
}
);

但最终的控制台.log(响应(产生:

Array[]

我想这失败了,因为在实际的 AJAX 调用完成之前,承诺序列正在通过 for 循环部分。如果我能弄清楚如何让它等待他们完成,我会在那里,但目前我被难住了。

另一种可以在其他情况下工作的解决方案是动态生成部分 html,并使用相应的文件内容更新正确的元素。不幸的是,这不是我的特定用例的选项。

有什么帮助吗?谢谢。

向后弯腰以使用承诺。为什么不只将名称放在数组中,并让一个函数执行获取,更新计数器并再次调用该函数?

var listOfFiles=["fileList.txt”],
cnt=0, 
oReq = new XMLHttpRequest();
function reqListener () {
if (listOfFiles[0]=="fileList.txt") {
listOfFiles = this.responseText.split(",");
}
else { 
processFile(this.responseText);
cnt++;
}
getFile();
}
oReq.addEventListener("load", reqListener);
function getFile() { 
if (cnt >= listOfFiles.length) return; 
oReq.open("GET", listOfFiles[cnt]);
oReq.send(); 
} 
getFile();

使用Promise.all(XHR 从示例中删除,但仍使用承诺(。

function getTOC() {
var jsonStr = JSON.stringify({
chapters: 2,
});
return Promise.resolve(jsonStr);
}
function getChapter(i) {
return Promise.resolve("chapter " + i);
}
getTOC()
.then(function(response) {
var chapters = JSON.parse(response)["chapters"];
return chapters;
})
.then(function(chapters) {
var promises = [];
for (i = 0; i < chapters; i++) {
promises.push(getChapter(i));
}
return Promise.all(promises);
})
.then(function(results) {
// results is an array of results, ordered as expected
console.log(results);
});

最新更新