我制作了一个 ajax post 函数,当我调用它一次时,传递给它的回调函数最终被调用了 3 次。 为什么多次调用回调?
我正在尝试使用一种“模块”javascript 模式,该模式使用闭包将类似的功能包装在一个全局变量下。我的 ajax 模块是它自己的文件,看起来像这样:
var ajax = (function (XMLHttpRequest) {
"use strict";
var done = 4, ok = 200;
function post(url, parameters, callback) {
var XHR = new XMLHttpRequest();
if (parameters === false || parameters === null || parameters === undefined) {
parameters = "";
}
XHR.open("post", url, true);
XHR.setRequestHeader("content-type", "application/x-www-form-urlencoded");
XHR.onreadystatechange = function () {
if (XHR.readyState === done && XHR.status === ok) {
callback(XHR.responseText);
}
};
XHR.send(parameters);
}
// Return the function/variable names available outside of the module.
// Right now, all I have is the ajax post function.
return {
post: post
};
}(parent.XMLHttpRequest));
主应用程序也是它自己的文件。例如,它看起来像这样:
// Start point for program execution.
(function (window, document, ajax) {
"use strict";
ajax.post("php/paths.php", null, function () { window.alert("1"); });
}(this, this.document, parent.ajax));
如您所见,我试图将依赖项作为局部变量/命名空间引入。当它运行时,它会弹出警告框 3 次。
我不确定这个问题是由于 ajax 函数本身还是整体架构(或两者兼而有之)造成的,所以我很感激对任何一个的评论或想法。
我试过从匿名函数中解开程序的主要部分,但这没有帮助。提前致谢!
编辑:
这是整个 HTML 文件,因此您可以看到我包含<script>
's 的顺序。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="expires" conent="0" />
<title>Mapalicious</title>
<link href="css/main.css" type="text/css" rel="stylesheet" />
<script src="js/raphael.js"></script>
</head>
<body>
<div id="map"></div>
<script src="js/promise.js"></script>
<script src="js/bigmap.js"></script>
<script src="js/ajax.js"></script>
<script src="js/init.js"></script>
</body>
</html>
编辑2:
我在我的例子中有一个错字,并改变了
(function (window, document, bigmap, ajax) {
至
(function (window, document, ajax) {
编辑 3:
我已经更改了onreadystatechange
将就绪状态记录到控制台的功能:
XHR.onreadystatechange = function () {
console.log("readyState: " + XHR.readyState);
if (XHR.readyState === done && XHR.status === ok) {
callback(XHR.responseText);
}
};
当我在谷歌浏览器中单步执行代码时,回调被调用了 3 次,控制台记录:
readyState: 4
readyState: 4
readyState: 4
但是,当我正常运行页面并且不单步执行时,该函数按预期工作并且只运行一次回调。在这种情况下,控制台会记录:
readyState: 2
readyState: 3
readyState: 3
readyState: 4
所以现在我的问题是,为什么在单步执行代码时会多次调用回调?
解决了:
当我问这个问题时,我没有意识到只有在调试时单步执行代码时才会发生这种情况。
所以,状态改变了 3 次,但是执行被断点延迟了,所以所有 3 个onreadystatechange
函数都看到了 4 的当前状态,而不是实际发生变化时的状态。
要点是onreadystatechange
更改不会存储该状态是什么。readyState
相反,它在执行时读取,即使程序被中断,同时状态再次发生变化。
因此,AJAX 需要与使用完全同步代码不同的调试技术……但您可能已经知道这一点。
感谢所有在这里提供帮助的人。