一、重複定時器數組
setTimeout(function() { // 處理中 setTimeout(arguments.callee, 1000); }, 1000)
這種模式鏈式調用了 setTimeout(), 每次函數執行的時候都會建立一個新的定時器,
第二個 setTimeout() 的調用使用了 arguments.callee 來獲取對當前執行函數的引用,併爲其設置另一個定時器。
這樣作的好處是在前一個定時器代碼執行完以前,不會向隊列插入新的定時器代碼,確保不會有任何缺失的間隔。瀏覽器
二、數組分塊處理函數
function chunk(array, process, context) { setTimeout(function() { var item = array.shift(); process.call(context, item); if (array.length > 0) { setTimeout(arguments.callee, 1000); } }, 1000); }
用法:this
var data = [12, 123, 234, 345, 456, 567]; function printValue(item) { console.log(item); } chunk(data, printValue);
數組分塊的重要性在於他能夠將多個項目的處理在執行隊列上分開,在每一個項目處理以後,給予其餘的瀏覽器處理機會運行,
這樣就可能避免長時間運行腳本的錯誤。spa
三、節流函數prototype
function throttle(method, context) { clearTimeout(method.tID); method.tID = setTimeout(function () { method.call(context); }, 1000); }
用法:code
function showTime() { console.log("nowDate:" + new Date().toLocaleDateString()); } setInterval(function () { throttle(showTime); }, 2000);
四、自定義事件blog
function EventTarget() { this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler: function (type, handler) { if (typeof this.handlers[type] == "undefined") { this.handlers[type] = []; } this.handlers[type].push(handler); }, fire: function (event) { if (!event.target) { event.target = this; } if (this.handlers[event.type] instanceof Array) { var handlers = this.handlers[event.type]; for (var i = 0, len = handlers.length; i < len; i++) { handlers[i](event); } } }, removeHandler: function (type, handler) { if (this.handlers[type] instanceof Array) { var handlers = this.handlers[type]; for (var i = 0, len = handlers.length; i < len; i++) { if (handlers[i] == handler) { break; } } handlers.splice(i, 1); } } };
用法:隊列
function handleMessage(event) { alert("Message received: " + event.message); } var target = new EventTarget(); target.addHandler("message", handleMessage); target.fire({type: "message", message: "Hello World"}); target.removeHandler("message", handleMessage);