1

我在 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 来停止代码吗?

谢谢您的帮助。

更新:感谢所有人,它现在可以工作了。

4

2 回答 2

0

XMLHttpRequest是一个异步操作。无论您的文件是否随时可用,或者即使没有涉及网络,都没有关系。因为它是一个异步操作,它总是在任何顺序/同步代码之后执行。这就是为什么您必须声明一个回调函数 ( ),当返回文件内容onreadystatechange时将调用该回调函数。open

通过上面的解释,您在此示例中的代码将不正确。该alert行将立即执行,而不是等待文件内容准备好。这项工作只会在onreadystatechange完成执行后完成,因此您必须alertonreadystatechange.

触发异步操作的另一种非常常见的方法是使用setTimeout,它强制其回调函数异步执行。在这里查看它是如何工作的。

编辑:您确实通过将第三个参数设置openfalsehttps://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#open())来强制请求同步。但是,在极少数情况下您希望这样的请求是同步的。考虑是否需要同步,因为在文件被读取之前,您将阻塞整个应用程序或网站。

于 2013-05-02T09:42:08.170 回答
0

那是因为您使用的是异步函数。使用异步函数时,您必须使用回调
回调是function cback()作为参数传递给另一个函数(例如 )的函数(例如function async())。嗯,必要cback的时候会用到async
例如,如果您正在执行读取文件或执行 SQL 查询等 IO 操作,则可以使用回调来处理检索到的数据:

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工作方式,每个异步任务都有自己的回调)。

于 2013-05-02T09:29:43.863 回答