我正在寫一個無處不在的插件長時間的函數回調爲ajax查詢阻止了GUI線程導致Firefox鎖定。有沒有一種正確的方式來在JavaScript的協作線程意義上「屈服」?
顯而易見的解決方案似乎是使用某種延遲執行(即我們要定期添加執行此查詢函數到事件隊列的末尾,然後允許執行其他命令。
我能想到這樣做的唯一方法是使用的setTimeout爲零的超時...這是保證工作,或者是有這樣做的更好的方法。
我正在寫一個無處不在的插件長時間的函數回調爲ajax查詢阻止了GUI線程導致Firefox鎖定。有沒有一種正確的方式來在JavaScript的協作線程意義上「屈服」?
顯而易見的解決方案似乎是使用某種延遲執行(即我們要定期添加執行此查詢函數到事件隊列的末尾,然後允許執行其他命令。
我能想到這樣做的唯一方法是使用的setTimeout爲零的超時...這是保證工作,或者是有這樣做的更好的方法。
使用setTimeout
與一個非常小的超時(0
或幾乎爲零,如果你覺得偏執)是在瀏覽器上下文中執行此操作的唯一方法。工作得很好,非常可靠,但一定要足夠頻繁,但不要太經常 ,因爲它需要一段時間才能回到你身邊(當然,在計算機意義上的「一段時間」它幾乎是瞬時的[用人的話來說,你可能正在做其他事情])。
所有現代瀏覽器實現都將setTimeout限制在〜10ms(基本上在所有非Windows系統上爲10ms,其中定時器分辨率要求<16ms定時器對功耗有顯着影響)。所以你並不需要擔心縮短超時時間。 – olliej 2009-09-20 23:32:34
@olliej:那是過時的信息(如果它在'09中是正確的,但是那也不是我的經驗)。瀏覽器的處理比這更復雜,這取決於'setTimeout'調用的起源。這是[幾年前在HTML5規範中編纂](http://www.w3.org/TR/html5/webappapis.html#timer-initialization-steps),但正如我所說,供應商已經在玩(不同)之前的遊戲。短版本:如果你的代碼沒有被定時器調用,你可以使用0,而現代瀏覽器會得到**非常**。 – 2015-10-21 11:57:21
請確保您使用異步請求作爲同步請求阻止瀏覽器(這將解釋GUI鎖定)。
如果這不是你的問題,我想你想要這樣的任務隊列。
var queue = [];
queue.push(someTaskFunction);
queue.push(anotherTaskFunction);
// ...
var runQueue = (function() {
var len = queue.length, task = 0;
for (; task < len; task++) {
yield queue[task]();
}
}());
呼叫runQueue.next()
執行下一個任務。用try..catch語句包裝它:
try {
runQueue.next();
} catch (e if (e instanceof StopIteration)) {}
你是怎麼做AJAX的?如果您正在加載腳本標記,則可能會阻止(瀏覽器阻止,直到腳本返回)。 – 2009-09-21 04:16:06
我正在使用jQuery.get – user47741 2009-09-21 13:46:16