我做了一个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));
Run Code Online (Sandbox Code Playgroud)
主应用程序也是它自己的文件.例如,它看起来像这样:
// 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));
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我正在尝试将依赖项作为局部变量/名称空间引入.当它运行时,它会弹出警报框3次.
我不确定这个问题是由于ajax函数本身还是整体架构(或两者),所以我很感激评论或想法.
我试过从匿名函数中解压缩程序的主要部分,但这没有帮助.提前致谢!
编辑:
这是整个HTML文件,所以你可以看到我包含的顺序<script>.
<!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>
Run Code Online (Sandbox Code Playgroud)
编辑2:
我的例子中有一个拼写错误,并且发生了变化
(function (window, document, bigmap, ajax) {
Run Code Online (Sandbox Code Playgroud)
至
(function (window, document, ajax) {
Run Code Online (Sandbox Code Playgroud)
编辑3:
我已经更改了onreadystatechange将就绪状态记录到控制台的功能:
XHR.onreadystatechange = function () {
console.log("readyState: " + XHR.readyState);
if (XHR.readyState === done && XHR.status === ok) {
callback(XHR.responseText);
}
};
Run Code Online (Sandbox Code Playgroud)
当我逐步浏览Google Chrome中的代码时,会调用三次回调,并且控制台会记录:
readyState: 4
readyState: 4
readyState: 4
Run Code Online (Sandbox Code Playgroud)
但是,当我正常运行页面并且不单步执行时,该函数按预期工作,只运行一次回调.在这种情况下,控制台记录:
readyState: 2
readyState: 3
readyState: 3
readyState: 4
Run Code Online (Sandbox Code Playgroud)
所以现在我的问题是,为什么在单步执行代码时多次调用回调?
解决了:
当我问这个问题时,我没有意识到只有在调试时单步执行代码时才会发生这种情况.
因此,状态更换3次,但执行已被破发点的延迟,因此所有3个onreadystatechange功能看到一个由4目前的状态,而不是什么状态是在变化实际发生.
外卖是onreadystatechange变化不存储该状态.相反,它会readyState 在执行时读取,即使程序被中断,状态也会在平均时间内再次发生变化.
因此,AJAX需要不同于使用完全同步代码的调试技术......但您可能已经知道了.
感谢所有在这里帮忙的人.
将readyState有4种不同的状态:
0 - 没有初始化请求
1 - 连接到服务器
2 - 收到请求
3 - 处理
4 - 完成,收到响应
这些更改中的每一个都将调用onreadystatechange处理程序.这就是为什么大多数这些函数看起来像这样:
xhr.onreadystatechange = function()
{
if (this.readyState === 4 && this.status === 200)
{
//do stuff with this.responseText
}
}
Run Code Online (Sandbox Code Playgroud)
只是硬编码他们,而不是使用不可靠的变量(名称done和ok看似危险的我).
除此之外,尝试post直接在返回的对象中声明该函数:
return {post : function()
{
};
Run Code Online (Sandbox Code Playgroud)
或者作为一个匿名.功能,分配给变量post:
var post = function(){};
Run Code Online (Sandbox Code Playgroud)
各种引擎通过功能,您声明它们的方式,提升它们来做各种事情.此外post,如果你问我感觉不对的函数名称...我想尝试使用的名称,不看像他们可能会被保留...
此外,您没有明确设置XHR的X-Requested-With标头:
XHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
Run Code Online (Sandbox Code Playgroud)
这可能只是造成问题的原因(HTTP1.1和传输编码分块?)
为了使调试更容易,请尝试通过更改callback(XHR.responseText);为每次警报显示时记录XHR对象callback.apply(this,[this.responseText]);,尽管参数是多余的.然后,ajax.post("php/paths.php", null, function () { window.alert("1"); });改为:
ajax.post("php/paths.php", null,
function (response)
{
console.log(this.readyState);//or alert the readyState
window.alert(response);//check the response itself, for undefined/valid responses
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7570 次 |
| 最近记录: |