函数在异步函数之前执行,即使使用了回调

  • 本文关键字:函数 回调 执行 异步 javascript
  • 更新时间 :
  • 英文 :


当我传递 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 秒。

最新更新