当我传递 LoadTask2作为回调时,我在读取文本文件完成之前执行 LoadTask2。 可能是什么原因以及如何在读取文本文件后执行 LoadTask2?
LoadTask1(LoadTask2);
function LoadTask1(LoadTask2) {
let parEtask1Pending = document.getElementById('task1Status');
parEtask1.replaceChild(loadingE, parEtask1Pending);
currentIntervalId = setInterval(function() {
readTextFile("file1.txt", getTextData);
}, 2000);
LoadTask2();
}
function LoadTask2() {
console.log("Task2")
}
function readTextFile(file, callback) {
console.log('Reading file..')
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "textFiles/" + file, true);
rawFile.onload = function() {
if (this.status === 200) {
getTextData(this.responseText);
}
}
rawFile.send();
}
输出为:任务2->读取文件。
问题就在这里:
function LoadTask1(LoadTask2) {
let parEtask1Pending = document.getElementById('task1Status');
parEtask1.replaceChild(loadingE, parEtask1Pending);
currentIntervalId = setInterval(function() {
readTextFile("file1.txt", getTextData);
}, 2000);
LoadTask2();
}
JavaScript不会等到setInterval
完成。setInterval
被执行并开始"并行"运行。
可能的解决方案是在readTextFile
中添加一个承诺,如下所示:
readTextFile = function(file) {
return new Promise(function(resolve, reject){
console.log('Reading file..')
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "textFiles/" + file, true);
rawFile.onload = function() {
if (rawFile.status === 200) {
resolve(rawFile.responseText);
}
rawFile.send();
}
}
现在,您可以在函数上放置一个.then()
:
function LoadTask1(LoadTask2) {
let parEtask1Pending = document.getElementById('task1Status');
parEtask1.replaceChild(loadingE, parEtask1Pending);
readTextFile("file1.txt").then(function(response){
console.log("your response: " + response);
LoadTask2();
})
}
还有另一种现代解决方案async/await
.你也可以这样做:
async function LoadTask1(LoadTask2) {
let parEtask1Pending = document.getElementById('task1Status');
parEtask1.replaceChild(loadingE, parEtask1Pending);
const responseText = await readTextFile("file1.txt");
console.log(responseText);
LoadTask2();
}
这应该有效,我还没有测试过。
此函数中还有一件事:
function readTextFile(file, callback) {
console.log('Reading file..')
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "textFiles/" + file, true);
rawFile.onload = function() {
if (this.status === 200) {
getTextData(this.responseText);
}
}
rawFile.send();
}
实际上,您不会将任何内容传递给回调函数。 您应该将getTextData(this.responseText)
重命名为callback(this.responseText)
,然后在回调函数中执行 task2,如下所示:
function readTextFile(file, callback) {
console.log('Reading file..')
var rawFile = new XMLHttpRequest();
rawFile.open("GET", "textFiles/" + file, true);
rawFile.onload = function() {
if (this.status === 200) {
callback(this.responseText);
}
}
rawFile.send();
}
function LoadTask1(LoadTask2) {
let parEtask1Pending = document.getElementById('task1Status');
parEtask1.replaceChild(loadingE, parEtask1Pending);
readTextFile("file1.txt", function(response){
console.log(response);
LoadTask2();
});
}
那是因为它是由于 setInterval 函数,它会在执行你的函数之前延迟 2 秒。