我在Javascript中给出了我的第一步,并试图了解它是如何工作的。 我遇到了代码执行顺序的问题。
var Parsed = [[]]
var txtFile = new XMLHttpRequest();
alert("Trying to open file!");
txtFile.open("GET", "http://foo/f2/statistics/nServsDistrito.txt", false);
txtFile.onreadystatechange = function() {
if (txtFile.readyState === 4) { // Makes sure the document is ready to parse.
if (txtFile.status === 200) { // Makes sure it's found the file.
alert("File Open");
allText = txtFile.responseText;
Parsed = CSVToArray(allText, ",")
}
}
}
txtFile.send(null);
alert("Job Done");
问题是“作业完成”首先出现在“文件打开”之后。
但该文件包含“作业完成”警报后代码所需的信息。 我更改了“get”请求的异步部分,但没有用。
当文件打开并检索到信息时,我能做些什么来支持所有代码? 在打开和解析文件时,我可以使用readyState来停止代码吗?
感谢您的帮助。
更新:现在感谢所有人。
答案 0 :(得分:0)
那是因为你正在使用异步功能。使用异步功能时,您必须使用回调
回调函数(例如function cback()
)作为参数传递给另一个函数(例如function async()
)。好的,cback
将在必要时由async
使用
例如,如果您正在执行IO操作(如读取文件或执行SQL查询),则回调可用于在检索后处理数据:
asyncOperation("SELECT * FROM stackoverflow.unicorns", function(unicorns) {
for(var i=0; i<unicorns.length; i++) {
alert("Unicorn! "+unicorns[i].name);
}
});
我们给出{匿名函数asyncOperation
作为第二个参数是“回调”,它将在查询数据准备好后执行。但是在处理该操作时,您的脚本未被阻止,这意味着如果我们在上一个代码之后添加此行:
alert("We are not blocked muahahaha");
在查询完成并显示独角兽之前,将显示该警报。
因此,如果你想在异步任务完成后之后执行,请在回调中添加该代码:
asyncOperation("SELECT * FROM stackoverflow.unicorns", function(unicorns) {
for(var i=0; i<unicorns.length; i++) {
alert("Unicorn! "+unicorns[i].name);
}
//add here your code, so that it's not executed until the query is ready
});
注意:正如@radhakrishna在评论中指出的那样,如果您传递open()
而不是true
,false
函数也可以以同步方式工作。这样代码就可以按照您的预期工作:一行一行,换句话说:同步。
回调可以用于很多事情,例如:
function handleData(unicorns) {
//handle data... check if unicorns are purple
}
function queryError(error) {
alert("Error: "+error);
}
asyncOperation("SELECT * FROM stackoverflow.unicorns", handleData, queryError);
这里我们使用两个回调,一个用于处理数据,另一个用于处理错误(当然这取决于asyncOperation
的工作原理,每个异步任务都有自己的回调)。
答案 1 :(得分:0)
XMLHttpRequest
是异步操作。无论您的文件是否随时可用,或者即使没有涉及网络也无关紧要。因为它是异步操作,所以在任何顺序/同步代码之后它将始终在之后执行。这就是为什么你必须声明一个回调函数(onreadystatechange
),当open
带回文件内容时将调用它。
通过上面的解释,此示例中的代码不正确。 alert
行将立即执行,而不是等待文件内容准备就绪。该工作仅在onreadystatechange
执行完毕后才能完成,因此您必须将alert
放在onreadystatechange
的末尾。
另一种触发异步操作的常用方法是使用setTimeout
,强制其异步执行回调函数。了解它的工作原理here。
编辑:您确实通过将第三个参数设置为open
到false
(https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#open())来强制请求同步。但是,极少数情况下,您希望这样的请求是同步的。考虑是否需要它是同步的,因为在读取文件之前,您将阻止整个应用程序或网站。