一种流行的技术不是等待来自服务器的响应来获得更新用户界面的许可,而是简单地假设继续更新 UI 是可以的。在大多数情况下,请求通常是成功的,所以只要做出这样的假设,然后向服务器发出请求。
之后,当响应返回时,不是更新 UI,而是检查请求是否确实成功。如果是的话,太好了!您可以什么都不做,因为您已经更新了 UI,或者您可以检查以确保您的快速更新与服务器发送的内容相匹配。它应该,但如果没有,你可以修复它。
此外,您还可以检查响应中的状态代码。如果它是 500、404 或任何非 200 状态代码,表明存在异常情况,那么您可以通过将您的点赞按钮恢复到之前的状态,然后向您的用户显示一条漂亮的错误消息来对其进行操作。
这不仅使您的 UI 非常灵活,而且您仍然能够在错误情况发生时处理它们。
这是您的代码,稍作修改以促进此技术。由于我没有您的所有代码,因此不能将其解释为一个工作示例,而只是为了让您入门:
function foo()
{
// call liked immediately. Don't wait for the server to respond
// think "update the UI immediately"
liked( function() {
xmlhttp2.open("POST", "async/async_likeEmail.php",true)
xmlhttp2.setRequestHeader(...
...
xmlhttp2.send(parameters);
});
// this is a handler where you just check to make sure the request succeeded
// if it does, great, do nothing. If it fails, change the like button back!
xmlhttp1.onreadystatechange = function() {
if(xmlhttp1.status == 404 || xmlhttp1.status == 503) {
alert("problem!");
// put the like button back to the previous state
}
};
xmlhttp1.open("POST", "async/async_likeUpdateDB.php", true)
xmlhttp1.setRequestHeader(...
...
xmlhttp1.send(parameters);
}
function liked(callback) {
/* insert code to render the liked result
* show what the button would look like if successful.
*/
// you don't really need to do this part. You know what a liked button looks like
// so just render it without waiting for the response.
// however, leaving this here acts as a failsafe in case your
// code that updates it immediately does something wrong
if (xmlhttp1.readyState == 4)
{
xmlhttp1.responseText;
someElement.innerHTML = xmlhttp1.responseText; // render the "liked" button
// call the callback to make the 2nd Ajax request
callback();
}
}
更新:
您的第一个 AJAX 调用未正确触发的原因是因为您将“喜欢”函数的结果分配给 onreadystatechange 处理程序,而不是将实际函数对象分配给 onreadystatechange 处理程序:
xmlhttp1.onreadystatechange = liked( function() {
xmlhttp2.open("POST", "async/async_likeEmail.php",true)
xmlhttp2.setRequestHeader(...
...
xmlhttp2.send(parameters);
}
相反,这会奏效:
xmlhttp1.onreadystatechange = function() {
liked( function() {
xmlhttp2.open("POST", "async/async_likeEmail.php",true)
xmlhttp2.setRequestHeader(...
...
xmlhttp2.send(parameters);
}
}
为了更清楚,请考虑以下几点:
xmlhttp1.onreadystatechange = someFunct(); // assign the result to the handler
xmlhttp1.onreadystatechange = someFunct; // assign the function to the handler
// also assigns function to handler, but wrapped in anonymous function
xmlhttp1.onreadystatechange = function() {
someFunct();
}