我在某些(但不是全部)IE7計算機上發生堆棧溢出錯誤。爲什麼通過XHR的異步onreadystatechange事件遞歸消耗棧?
該函數下載一堆基於URL的資源,並對它們不做任何處理。它在我的登錄頁面上運行,其目的是在您輸入憑證時獲取靜態內容,以便在您真正需要時輸入它的本地緩存。
// Takes an array of resources URLs and preloads them sequentially,
// but asynchronously, using an XHR object.
function preloadResources(resources) {
// Kick it all off.
if (resources.length > 0) {
var xhr = getXHRObject(); // Prepare the XHR object which will be reused for each request.
xhr.open('GET', resources.shift(), true);
xhr.onreadystatechange = handleReadyStateChange;
xhr.send(null);
}
// Handler for the XHR's onreadystatechange event. Loads the next resource, if any.
function handleReadyStateChange() {
if (xhr.readyState == 4) {
if (resources.length > 0) {
xhr.open('GET', resources.shift(), true);
xhr.onreadystatechange = arguments.callee;
xhr.send(null);
}
}
}
// A safe cross-browser way to get an XHR object.
function getXHRObject() {
// Clipped for clarity.
}
} // End preloadResources().
它被稱爲是這樣的:
preloadResources([
'http://example.com/big-image.png',
'http://example.com/big-stylesheet.css',
'http://example.com/big-script.js']);
它遞歸處理URL的數組。我認爲它不容易出現堆棧溢出錯誤,因爲每次遞歸都是從異步事件調用的 - XHR的onreadystatechange
事件(請注意,我正在異步調用xhr.open()
)。我覺得這樣做會阻止它成長。
我不明白堆棧如何失去控制? 我哪裏錯了?
感謝您的答覆,斯科特。正在評估'arguments.callee'。關於您引用的文章,原作者的作者寫了一篇[後續](http://radio.javaranch.com/pascarello/2006/03/31/1143817890773.html),稱xhr.abort()是不必要的你在調用'xhr.open()'後設置'onreadystatechange'的處理程序。 –