複数の AJAX 要求を迅速または同時に送信する必要がある AJAX 集中型アプリケーションがあります。次のコードは、アプリ全体で使用する AJAX POST 呼び出しを送信するための単純なラッパーです。2 つの注意事項があります。
1)リクエストを行う前にユーザーのインターネット接続をテストできるようにしたいので、接続がダウンしている場合に通知できます。
2) 接続がダウンしていて、アプリを引き続き使用すると、より多くの AJAX 呼び出しが生成される場合、それらの呼び出しをキューに入れ、接続が回復したら 1 つずつ送信したいと考えています。
接続チェックとキューイングは機能しますが、ユーザーがオンラインに戻ったときに、要求の一部のみがサーバーに送信され、元の順序で送信されたように見えます。私は何が欠けていますか?すべてのリクエストが送信されていないのはなぜですか? また、順番どおりに送信されていないのはなぜですか?
そして、誰かが気付く前に、jQuery を使用したこのトピックに関する他の解決策をいくつか見てきました。私はそれらを使用することに反対しているわけではありません。このコードが機能しない理由を理解したいだけです。前もって感謝します。
window.connectionState = true
window.xhrQueue = []
window.pingInterval
function xhrPost(url, packet, before, after) {
if (!url || typeof(url) !== "string") {
console.log("invalid url supplied in xhr call.")
return false
}
var mainRequest = function() {
var xhr= new XMLHttpRequest()
if (typeof(after) === "function") {
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
after(xhr)
return true
}
}
}
if (typeof(before) === "function") {
before()
}
xhr.open("POST",url,true)
if (packet) {
xhr.send(JSON.stringify(packet))
}
else {
xhr.send()
}
}
ping(mainRequest)
}
function ping(mainRequest) {
// Create pingXhr to test connection
var pingXhr = new XMLHttpRequest()
pingXhr.onreadystatechange = function(){
// If pingXhr comes back successfully...
if (pingXhr.readyState == 4) {
if (pingXhr.status == 200) {
// If pingXhr comes back from being down, update user
if (window.connectionState !== true) {
setTimeout(function() { alert("And we're back! Your connection seems to be working now. Keep editing.") }, 1)
}
// If there are requests waiting, send them in order, then remove them
if (window.xhrQueue.length > 0) {
for (var i in window.xhrQueue) {
ping(window.xhrQueue[i])
window.xhrQueue.splice(i, 1)
clearInterval(window.pingInterval)
}
}
// Otherwise, just make the singular request
else {
mainRequest()
}
// Reset xhrQueue since stuff is successful, change connection to true, and unset onbeforeunload message
window.xhrQueue = []
window.connectionState = true
}
// If there was a problem with the request
else {
// Notify the user their internet is down
if (window.connectionState === true) {
setTimeout(function() { alert("It seems you have momentarily lost internet connectivity.") }, 1)
}
// If there are no requests in the xhrQueue, create the timeout. Otherwise, just add to the queue
if (window.xhrQueue.length === 0) {
window.pingInterval = setInterval(function(){ ping() }, 3000)
}
// Add the request to the xhrQueue to be processed in order
if (typeof(mainRequest) === "function") {
window.xhrQueue.push(mainRequest)
}
window.connectionState = false
}
}
}
pingXhr.open("GET","/some/url/here",true)
pingXhr.send()
}