Javascript执行代码顺序

时间:2013-05-02 09:03:32

标签: javascript ajax asynchronous xmlhttprequest

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

感谢您的帮助。

更新:现在感谢所有人。

2 个答案:

答案 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()而不是truefalse函数也可以以同步方式工作。这样代码就可以按照您的预期工作:一行一行,换句话说:同步。


回调可以用于很多事情,例如:

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

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