ユーザー インターフェイスを更新する許可を得るためにサーバーからの応答を待つ代わりに、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 ハンドラーに割り当てるのではなく、"liked" 関数の結果を 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();
}