一、重复定时器数组
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);