一些工具函数

随机数 random

/**
 * 随机数 [min, max]
 * @param {Number} min 最小值
 * @param {Number} max 最大值
 */
function random (min, max) {
  return Math.ceil(Math.random() * (max - min) + min);
}

setInterval 和 setTimeout

class Time {
  constructor () {
    // 对象字面量 改用class 数据隔离 转为私有变量 两个计时器之间不相互影响
    this.timer = null;
  }
  /**
   * 等待指定时间后调用函数
   * @param {Function} fn 处理函数
   * @param {Number} duration 等待时间 单位ms
   */
   setTimeout(fn, duration = 1000) {
    this.clear()
    this.timer = setTimeout(fn, duration)
    return this.timer
  }
  /**
   * 等待指定时间
   * @param {Number} duration 等待时间 单位ms
   * @return {Promise}
   */
  delay(duration = 1000) {
    return new Promise((resolve) => {
      this.setTimeout(() => {
        resolve(this.timer)
      }, duration)
    })
  }
  /**
   * 间隔指定时间调用函数
   * @param {Function} fn 处理函数
   * @param {Number} duration 间隔时间 单位ms
   */
  setInterval(fn, duration) {
    // this指向time
    this.setTimeout(() => {
      // this指向time
      fn()
      this.setInterval(fn, duration)
    }, duration)
    return this.timer
  }
  clear() {
    clearTimeout(this.timer)
    this.timer = null
  }
}

原因:setInterval和setTimeout的缺陷和优势分析

栗子

const time = new Time();
time.setInterval(() => {
	console.log(this);
});
time.clear();	// 销毁组件 销毁计时器

防抖 debounce + promise

/**
 *@description 防抖 debounce + promise
 * 栗子:实时搜索,拖拽
 * @param {Function} fn 函数
 * @param {Number} delay = [500] 时延
 * @param {Boolean} immediate = [false] 是否立即执行
 */
function debounce(fn, delay = 500, immediate = false) {
	// 1.定义一个定时器, 保存上一次的定时器
	let timer = null;
	let isInvoke = false;

	// 2.真正执行的函数
	const _debounce = function(...args) {
		return new Promise((resolve, reject) => {
			// 取消上一次的定时器
			if (timer) clearTimeout(timer);

			// 判断是否需要立即执行
			if (immediate && !isInvoke) {
				const result = fn.apply(this, args);
				if (isPromise(result)) {
					result.then(resolve).catch(reject);
				} else {
					resolve(result);
				}
				isInvoke = true;
			} else {
				// 延迟执行
				timer = setTimeout(() => {
					const result = fn.apply(this, args);
					if (isPromise(result)) {
						result.then(resolve).catch(reject);
					} else {
						resolve(result);
					}
					isInvoke = false;
					timer = null;
				}, delay)
			}
		});
	};

	// 封装取消功能
	_debounce.cancel = function() {
		if (timer) clearTimeout(timer);
		timer = null;
		isInvoke = false;
	}
	
	return _debounce;
}

function isPromise(value) {
	if (Object.prototype.toString.call(value) !== '[object Promise]') return false;
	if (typeof(value.then) !== 'function') return false;
	if (typeof(value.catch) !== 'function') return false;
	return true;
}

栗子

function delay (duration = 1000) {
	return new Promise((resolve) => {
		setTimeout(resolve, duration);
	});
}
const debounceChange = debounce(async (...args) => {
	console.log('--- async fn start --->', ...args);
	await delay(5000);
	console.log('--- async fn end --->', ...args);
	return 'async resolved';
}, 1000);

// const debounceChange = debounce((...args) => {
// 	console.log('--- fn end --->', ...args);
// 	return 'resolved';
// }, 3000);

debounceChange('给fn的参数').then((res) => {
	console.log('--- then 1 --->', res);
});

debounceChange('给fn的参数').then((res) => {
	console.log('--- then 2 --->', res);
});

参考:防抖和节流(附带promise版)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值