12345678910111213141516171819202122232425262728293031323334353637383940414243 |
- module.exports = function (func, wait, options) {
- /* options的默认值
- * 表示首次调用返回值方法时,会马上调用func;否则仅会记录当前时刻,当第二次调用的时间间隔超过wait时,才调用func。
- * options.leading = true;
- * 表示当调用方法时,未到达wait指定的时间间隔,则启动计时器延迟调用func函数,若后续在既未达到wait指定的时间间隔和func函数又未被调用的情况下调用返回值方法,则被调用请求将被丢弃。
- * options.trailing = true;
- * 注意:当options.trailing = false时,效果与上面的简单实现效果相同
- */
- var context, args, result;
- var timeout = null;
- var previous = 0;
- if (!options) options = {};
- var later = function () {
- previous = options.leading === false ? 0 : new Date().getTime();
- timeout = null;
- result = func.apply(context, args);
- if (!timeout) context = args = null;
- };
- return function () {
- var now = new Date().getTime();
- if (!previous && options.leading === false) previous = now;
- // 计算剩余时间
- var remaining = wait - (now - previous);
- context = this;
- args = arguments;
- // 当到达wait指定的时间间隔,则调用func函数
- // 精彩之处:按理来说remaining <= 0已经足够证明已经到达wait的时间间隔,但这里还考虑到假如客户端修改了系统时间则马上执行func函数。
- if (remaining <= 0 || remaining > wait) {
- // 由于setTimeout存在最小时间精度问题,因此会存在到达wait的时间间隔,但之前设置的setTimeout操作还没被执行,因此为保险起见,这里先清理setTimeout操作
- if (timeout) {
- clearTimeout(timeout);
- timeout = null;
- }
- previous = now;
- result = func.apply(context, args);
- if (!timeout) context = args = null;
- } else if (!timeout && options.trailing !== false) {
- // options.trailing=true时,延时执行func函数
- timeout = setTimeout(later, remaining);
- }
- return result;
- };
- };
|