3.2.1 取消待处理的请求
如果在服务器端发生错误,也就意味着返回内容的状态值不是200,则必须决定如何处理。假设遇到的是“file is not found”(文件未找到,404)或“internal server error occurred”(内部服务错误,302),由于这些错误只有管理员能够修复,因此在几分钟内重试是没有效果的。处理这种情况的最简单方法是取消所有待处理的请求。你可以在代码中的某处设置一个标志,说明“不要再发送请求了”。这显然对于使定期刷新模式的解决方案有很大的影响。
对于新评论提示的例子,可以通过修改来考虑该问题。这是一个Ajax解决方法为用户提供增值,而并非关注页面的例子。如果请求失败,不必向用户发出警告;你可以简单地取消后续的请求来避免更多的错误。要实现这一功能,必须添加一个全局变量,用来说明是否允许发送请求:
var oXmlHttp = null;
var iInterval = 1000;
var iLastCommentId = -1;
var divNotification = null;
var blnRequestsEnabled = true;
现在,在发送请求之前必须先检查变量blnRequestsEnabled的值。这可以通过将checkComments()函数的主体封装到一个if语句中来实现:
function checkComments() {
if (blnRequestsEnabled) {
if (!oXmlHttp) {
oXmlHttp = zXmlHttp.createRequest();
} else if (oXmlHttp.readyState != 0) {
oXmlHttp.abort();
}
oXmlHttp.open("get", "CheckComments.php", true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
var aData = oXmlHttp.responseText.split("||");
if (aData[0] != iLastCommentId) {
if (iLastCommentId != -1) {
showNotification(aData[1], aData[2]);
}
iLastCommentId = aData[0];
}
setTimeout(checkComments, iInterval);
}
}
};
oXmlHttp.send(null);
}
}
但工作还没有全部完成,还必须检查可能遇到的两种不同类型的错误:给出了状态码的服务器错误;服务器不可达错误(例如服务器宕机或因特网连接失效)。
首先,将最外层的if语句中的内容封装到try...catch程序块中。当服务器不可达时,不同的浏览器响应的时间不同,但都会抛出错误。将这些请求封装在try...catch中,可以确保捕获其抛出的任何错误,在那里可以将blnRequestsEnabled设置为false。接下来,对于服务器错误而言,可以在状态不等于200时抛出一个自定义的错误。这时try...catch程序块将捕获这个错误,其效果与服务器不可达的错误一样(将blnRequestsEnabled设置为false):
function checkComments() {
if (blnRequestsEnabled) {
try {
if (!oXmlHttp) {
oXmlHttp = zXmlHttp.createRequest();
} else if (oXmlHttp.readyState != 0) {
oXmlHttp.abort();
}
oXmlHttp.open("get", "CheckComments.php", true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
var aData = oXmlHttp.responseText.split("||");
if (aData[0] != iLastCommentId) {
if (iLastCommentId != -1) {
showNotification(aData[1], aData[2]);
}
iLastCommentId = aData[0];
}
setTimeout(checkComments, iInterval);
} else {
throw new Error("An error occurred.");
}
}
};
oXmlHttp.send(null);
} catch (oException) {
blnRequestsEnabled = false;
}
}
}
现在,不管出现哪种错误,都将抛出一个异常,并且变量blnRequestEnable的值将设置为false,如果再次调用checkComments(),将有效地取消后续的请求。
你可能还会发现,只有当状态为200时,才对另一个请求创建超时时间,它是为了防止遇到其他状态的请求。这对于服务器错误而言可以正常工作,但对于通信错误则无能为力。因此遇到这类错误时,通常最好有多种处理错误的方法。







