防抖节流函数

一、防抖函数

1.封装防抖函数后进行使用

mounted() {
    //接收debounce返回来的函数    
    //this.$refs.scroll.refresh不能加(),因为要传进一个函数,加入括号变成了接收函数内部的值
    const refresh = this.debounce(this.$refs.scroll.refresh, 500);
    this.$bus.$on("imgLoad", () => {
      refresh();//调用函数
    });
  },
  methods: {
    /**
     * 构造防抖函数
     */
    debounce(fun, delay) {
      let timer = null;
      return function(...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
          fun.apply(this, args);
        }, delay);
      };
    },
}

2.使用封装的方式

//封装的debounce.js函数
//delay=50是默认值,es6语法
export function debounce(fun, delay=50) {
  let timer = null;
  return function(...args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fun.apply(this, args);
    }, delay);
  };
}
//增加let that=this
function debounce(fun, delay = 300) {
let timer = null
return function (...args) {
let that = this //引用this的指向
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fun.apply(that, args)
}, delay)
}
}

// 编写立即执行函数
function debounce(fn, delay, immediate = false) {
	let timer = null;
	let isInvoke = false;
	return function (...args) {
		if (timer) clearTimeout(timer);
		if (immediate && !isInvoke) {
			fn.apply(this, args);
			isInvoke = true;
		} else {
			timer = setTimeout(() => {
				fn.apply(this, args);
				isInvoke = false;
			}, delay);
		}
	};
}
//添加了回调函数Promise和resultCallback

const input = document.querySelector('input');

const button = document.querySelector('button');

const inputFun = function () {
	console.log('发送了网络请求');
	return 'hello world';
};

function debounce(fn, delay, immediate = false, resultCallBack = function (res) {}) {
	let timer = null;
	let isInvoke = false;
	const _debounce = function (...args) {
		return new Promise((resolve, reject) => {
			if (timer) clearTimeout(timer);
			if (immediate && !isInvoke) {
				try {
					const result = fn.apply(this, args);
					resultCallBack(result);
					isInvoke = true;
					resolve(result);
				} catch (error) {
					reject(error);
				}
			} else {
				timer = setTimeout(() => {
					try {
						const result = fn.apply(this, args);
						resultCallBack(result);
						isInvoke = false;
						timer = null;
						resolve(result);
					} catch (error) {
						reject(error);
					}
				}, delay);
			}
		});
	};

	_debounce.cancel = () => {
		clearTimeout(timer);
		timer = null;
		isInvoke = false;
	};
	return _debounce;
}

function foo(res) {
	console.log('res :>> ', res);
}

const debounceFun = debounce(inputFun, 500, false);

const tempCallback = () => {
	debounceFun().then((res) => {
		console.log('我是封装的函数', res);
	});
};

input.oninput = tempCallback;
//使用封装的debounce
import debounce from xxx
mounted() {
    const refresh = this.debounce(this.$refs.scroll.refresh, 500);
    this.$bus.$on("imgLoad", () => {
      refresh();//调用函数
    });
  },

二、节流函数

  function throttle(fun, delay = 1000) {
    let pre = 0
    return function (...args) {
      let now = Date.now()
      let that = this
      if (now - pre > delay) {
        fun.apply(that, args)
        pre = now
      }
    }
  }

合成版本

// 合成版
/**
   * @desc 函数防抖
   * @param func 目标函数
   * @param wait 延迟执行毫秒数
   * @param immediate true - 立即执行, false - 延迟执行
   */
function debounce(func, wait, immediate) {
    let timer;
    return function() {
      let context = this,
          args = arguments;
           
      if (timer) clearTimeout(timer);
      if (immediate) {
        let callNow = !timer;
        timer = setTimeout(() => {
          timer = null;
        }, wait);
        if (callNow) func.apply(context, args);
      } else {
        timer  = setTimeout(() => {
          func.apply(context, args);
        }, wait)
      }
    }
}
/**
 * @desc 函数节流
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */
function throttle(func, wait, type) {
  if (type === 1) {
    let previous = 0;
  } else if (type === 2) {
    let timeout;
  }
  return function() {
    let context = this;
    let args = arguments;
    if (type === 1) {
        let now = Date.now();
 
        if (now - previous > wait) {
          func.apply(context, args);
          previous = now;
        }
    } else if (type === 2) {
      if (!timeout) {
        timeout = setTimeout(() => {
          timeout = null;
          func.apply(context, args)
        }, wait)
      }
    }
  }
}

在Vue的methods中使用

    methods: {
        toPay: Taro.debounce(
            function() {
                this.$emit("goToPay");
            },
            1000,
            true
        ),
        goToPay() {
            console.log("123");
            this.toPay();
        }
    }

Vue的methods中使用防抖节流:https://www.cnblogs.com/luckrain7/p/12670473.html

B站视频链接(防抖函数):https://www.bilibili.com/video/BV15741177Eh?p=175

博客链接:https://www.cnblogs.com/cc-freiheit/p/10827372.html

posted @ 2020-07-26 23:32  Wayhome'  阅读(334)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css