2017-09-01 64 views
-1

我有一個圖像需要根據AJAX調用的結果顯示。我不加載像基金會這樣的jQuery和其他庫,它負責基於設備加載負責任的圖像。JavaScript - 時間問題 - 如何等待請求

AJAX呼叫的響應時間範圍爲800-1000毫秒。如果響應超過1000毫秒,我會顯示一個默認圖像。另外,我應該在發送第一個請求時發送AJAX請求,因此它立即被設置爲標題的第一個子節點。 JSFiddle for Timing issue

<html><head><script>set Timeout of 1000 ms .....xhr.send();</script> 
<body> 
    <div id="id_in_response" style="display:none"><img src="xyz"></div> 
    <div id="default_on_timeout" style="display:none"><img src="xyz"></div> 
....Loads of Elements..... 
<footer> 
    <script src="jquery.js"></script> 
    <script src="foundation.js"></script> 
    <script src="custom.js"></script> 
</body> 

定製JS的說明: 自定義JS將執行基業庫JS加載響應圖像。

問題是XHR應該如何與custom.js函數進行通信,以確定是否需要處理超時或響應。我無法使用jQuery Promise,因爲在下載HTML之後,jQuery將加載。我無法使用Native Promises。 可能是在XHR響應進入時,但custom.js仍未加載或解析。我也不能認爲,共振時間總是在800-1000毫秒的範圍內。它甚至可能降到300毫秒或更少。

Custome JS代碼:

$(document).foundation({interchange : named_queries {....}}); 

// This will parse all the image tags , Run media Query and attach an 
appropriate source to the image 

最終解決方案:enter link description here

+1

'我不能使用Promise,因爲jQuery將在HTML之後加載,這沒有任何意義...... Promise與jQuery無關 –

+0

我應該使用setInterval - wouldnt阻止頁面嗎? – user1428716

+0

@JaromandaX:或許他/她在談論jQuery的'$ .Deferred'而不是原生承諾。 –

回答

1

窮男人的 「未來」 代碼

var specialRequest = (function() { 
    var cb; 
    var cberr; 
    var xhr = new XMLHttpRequest(); 
    var doCallback = function(err) { 
     if (cb === undefined) { 
      cb = true; 
      cberr = err; 
     } else if (typeof cb === 'function') { 
      cb(err, xhr); 
     } 
    }; 
    var timeout = setTimeout(function() { 
     xhr.abort(); //?? 
     doCallback('timeout'); 
    }, 1000); 
    xhr.open('GET', 'whatever/your/url/is'); 
    xhr.onload = function() { 
     doCallback(null); 
    } 
    xhr.onerror = function() { 
     doCallback('error'); 
    } 
    xhr.onloadend = function() { 
     // if the XHR finishes before the setTimeout, cancel it 
     clearTimeout(timeout); 
    } 
    xhr.send(); 

    return function(callback) { 
     if (cb === undefined) { 
      cb = callback; 
     } else if (cberr !== null) { 
      callback(cberr, xhr); 
     } 
    } 
})(); 

,然後在custom.js

specialRequest(function(error, xhr) { 
    if (error) { 
     // handle error 
    } else { 
     // handle success 
    } 
}); 

比較這與無極代碼

var myPromise = new Promise(function(resolve, reject) { 
    var xhr = new XMLHttpRequest(); 
    var timeout = setTimeout(function() { 
     reject(new Error('timeout')); 
    }, 1000); 
    xhr.open('GET', 'whatever/your/url/is'); 
    xhr.onload = function() { 
     resolve(xhr); 
    } 
    xhr.onerror = function() { 
     reject(new Error('error')); 
    } 
    xhr.send(); 
}); 
在custom.js

//

myPromise.then(function(xhr) { 
    // handle success 
}).catch(function(reason) { 
    // handle failure 
}); 
+0

我仍然不能使用它 - onload應該執行我在custom.js中的基礎代碼。它將如何做。這可能是custom.js仍在加載.. – user1428716

+0

正確...你可以改變'custom.js'嗎?這是Promises在公園散步的地方:p –

+0

是的,我可以改變。 – user1428716

0

我應該使用的setInterval - 難道不阻斷網頁?

不,它不會;但是您使用setTimeout而不是setInterval來建立您的1000毫秒超時。例如,大致

var timer = setTimeout(function() { 
    // Use default image instead 
}, 1000); 
var xhr = new XMLHttpRequest(/*...*/); 
xhr.send(/*...*/); 
xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4 && xhr.status == 200) { 
     if (/*...you haven't already used the default image...*/) { 
      clearTimeout(timer); 
      // Use the appropriate image... 
     } 
    } 
}; 

注意的是,上述不成立的頁面中,我強烈建議做的顯示。只要填寫圖片,當你知道要填寫什麼圖像(如上)。

+0

啊。 xhr.onreadystatechange - 我可以寫在我的自定義js ..這工作正常 – user1428716

+0

其實它不工作正常 - 如果我寫xhr.onreadyState在自定義JS - 它會失敗,如果響應來得太早,即100毫秒..所以我猜測polyfill承諾是最好的解決方案 – user1428716

+0

@ user1428716:「它失敗」沒有告訴我們很多,承諾也不會在這裏有用。這聽起來像你在問題中沒有描述的東西有問題。我建議堅持下去,調試失敗,如果你仍然無法解決問題,用一個[mcve]發佈一個新問題來證明失敗。人們會很樂意提供幫助。 –