我使用以下代码每3秒发送一次ajax请求:
var refreshId = setInterval(function() {
$.ajax({
async: true,
url: 'gohere',
dataType: 'text',
cache: false,
timeout: 5000,
success: function(result, textStatus, XMLHttpRequest) {
alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status);
}
});
}, 3000);
问题是,即使主服务器不可访问(例如未连接到LAN),也会调用成功函数而不是带有“timeout”-status的错误函数(在Ubuntu 10.04上测试)使用FireFox 3.6.7) (如果没有定期请求,它将正常工作:在超时时,使用正确的'timeout'-statusText调用错误函数。)
success-alert-function将在超时时显示以下文字:
textStatus: success, XHR.readyState: 4, XHR.status: 0所以我需要使用XHR.status值,成功时应该是200,以确定错误。 这是正常行为还是我做错了什么?
答案 0 :(得分:3)
考虑在成功和错误处理程序中移动setTimeout,并使其异步递归。
var refreshId = function() {
$.ajax({
async: true,
url: 'gohere',
dataType: 'text',
cache: false,
timeout: 5000,
success: function(result, textStatus, XMLHttpRequest) {
alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status);
setTimeout(refreshId, 3000);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status);
setTimeout(refreshId, 3000);
}
});
};
事情是,setTimeout和setInterval时间不可靠,尤其是警报。只要警报对话框保持打开状态,警报就会停止javascript。此外,setTimeout和setInterval不会中断当前运行的代码以保证完美的时间,它们将等到javascript线程在代码执行之间有一个开放和跳转。
使用之前的代码设置,您还有可能在refreshId调用2之后,refreshId调用1的响应将到达,因为http往返占用了一定的时间。
通过使你的setTimeout依赖于所引入的响应,你可以获得更稳定和透明的结果。
答案 1 :(得分:0)
好吧,搞乱异步函数回调可能会变得凌乱:)。 setInterval()
就是其中之一,.ajax()
也是如此。
您应该尝试使用setTimeout()
,并在最后一次完成时拨打下一个.ajax()
来电。
(function repeat(){
$.ajax({
async: true,
url: 'gohere',
dataType: 'text',
cache: false,
timeout: 5000,
success: function(result, textStatus, XMLHttpRequest) {
alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status);
},
complete: function(XMLHttpRequest){
setTimeout(repeat, 3000);
}
});
}());
如果您坚持.ajax()
尽可能接近3
秒,则可以在启动新的ajax请求之前中止该请求。
因此,将变量分配给.ajax()
的返回
var currentxhr = $.ajax({});
并在beforeSend
来电中添加.ajax()
个回调。在该处理程序调用中
currentxhr.abort();
这将中止可能正在运行的请求。
答案 2 :(得分:0)
而不是查看textStatus
使用此测试:xhr.statusText.toUpperCase() === 'OK'
我遇到了FF 3.6.8在301页面上有xhr.status === 0
的问题。我在httpSuccess
函数中添加了上面的jQuery 1.4.2:
return !xhr.status && location.protocol === "file:" ||
// Opera returns 0 when status is 304
( xhr.status >= 200 && xhr.status < 300 ) ||
xhr.status === 304 || xhr.status === 1223 ||
( xhr.status === 0 && xhr.statusText.toUpperCase() === 'OK');
答案 3 :(得分:0)
我相信你应该研究http://plugins.jquery.com/project/ajaxqueue,这是为了管理ajax竞争条件。