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();
}
输出为:Task2->Reading file。
解决方案
问题在这里:
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();
});
}
推荐阅读
- flutter - 调用通用回调时出现 TypeError
- github - 有没有办法将 GitHub 存储库的安全建议提取到 CSV 文件中?
- delphi - CEF4Delphi 处理打开选项卡(并下载文件)
- python - django postgres delete 的性能问题
- jquery - Angular,如何在从服务器获取数据并应用 *ngFor 后通过 Jquery 获取类?
- php - 类不是有效的实体或映射的超类
- c - 我可以用 Tun/Tap 接口 ping 吗
- ios - 单击按钮未打开视图
- python - Python - 打开带有参数的 lnk 文件 (FlashProgrammer)
- jenkins - jenkins jira 触发器插件无法与 Jira 云一起使用