我一直在自学php和xml(以及其他语言),并且在进行w3schools的xmlhttprequest教程时,我注意到open()和send()函数位于函数的末尾,而不是在函数的末尾或出来。这有点令人困惑,因为如果尚未发送请求,如何从服务器获得响应?我可能错过了一些简单的事情,如果是这样,我道歉,但是有人可以帮助我解决我的困境吗?预先感谢
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
答案 0 :(得分:0)
读取数据的代码将在一个单独的函数中,该函数被分配为事件处理程序。
该功能直到收到响应后才会运行。
答案 1 :(得分:0)
这在现代浏览器上可能无关紧要,但从根本上讲,您可以在发送呼叫之前进行设置。特别是,这样所有处理程序都在 之前被附加,要求XHR做某事。比较:
// Example 1
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() {
// Got the data
});
xhr.open("GET", "http://example.com");
xhr.send();
使用
// Example 2
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com");
xhr.send();
xhr.addEventListener("load", function() {
// Got the data
});
浏览器不是单线程的,尽管它们在单个主线程(以及您创建的所有Web Worker)中运行JavaScript代码。因此,可能(尽管非常不可能),对于示例2,如果资源位于浏览器的缓存中,则单独的线程处理网络调用可能会触发load
JavaScript线程上的send
和addEventListener
调用之间发生事件,请参见未注册任何处理程序,并且不将任务排队等待事件循环调用该处理程序。而对于示例1,如果它在send
时立即触发加载事件,它将看到一个附加的处理程序并将请求的任务排队(稍后在事件循环处理该任务时运行)。 >
以下是该假设情况的示例,显示了线程交互:
Example 1 - Highly Theoretical Scenario JavaScript Thread Network Thread ----------------------------------------- -------------- var xhr = new XMLHttpRequest(); xhr.addEventListener("load", function() { // Got the data }); xhr.open("GET", "http://example.com"); xhr.send(); (Within send: Start the send, handing off to the network thread) 1. Start a GET on `xhr` 2. It's in cache, are there any load handlers registered on `xhr`? 3. Yes, queue a task to call the handler (Done with current task) (Pick up next task) Call the handler
vs
Example 2 - Highly Theoretical Scenario JavaScript Thread Network Thread ----------------------------------------- -------------- var xhr = new XMLHttpRequest(); xhr.open("GET", "http://example.com"); xhr.send(); (Within send: Start the send, handing off to the network thread) 1. Start a GET on `xhr` 2. It's in cache, are there any load handlers registered on `xhr`? 3. No, don't queue a task to call the handler xhr.addEventListener("load", function() { // Got the data }); (Done with current task) (Pick up next task) (No task, do nothing)
我非常怀疑,任何当前的浏览器实际上都可以做到这一点(示例2),而且我不知道XHR过去曾遇到过这样的问题。但这在理论上是可能的,大约在2008年,存在一个非常相似的问题,在为src
挂起之前,在img
元素上设置load
。但是,浏览器已解决了该问题,我很惊讶地发现它们现在可以接受上述示例2的情况,即使它们过去可能不在某个时候。
在实践中,我怀疑这很重要。但是如果我使用XMLHttpRequest
(我不使用fetch
),我仍然会使用Example 1。