
目录

- <input type="text" />
-
-
- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.4/underscore-umd-min.js">script>
-
- <script>
- // 2.获取input元素
- const inputEl = document.querySelector('input');
-
- // 3.防抖处理代码
- let counter = 1;
- inputEl.oninput = _.debounce(function () {
- console.log(`发送网络请求${counter++}:`, this.value);
- }, 1000);
- script>

- <input type="text" />
- <script>
- function starDebounce(fn, delay) {
- // 1.用于记录上一次事件触发的timer
- let timer = null;
- // 2. 返回新的函数
- return function () {
- // 3. 如果有再次触发(更多次触发)事件, 那么取消上一次的事件
- if (timer) clearTimeout(timer);
- // 4. 绑定当前事件
- timer = setTimeout(() => {
- // 5. 延迟后执行
- fn();
- // 6. 执行后把当前定时器删除
- timer = null;
- }, delay);
- };
- }
- script>
- <script>
- const inputDom = document.querySelector('input');
- let counter = 1;
- inputDom.oninput = starDebounce(function () {
- console.log(`发送网络请求${counter++}`);
- }, 1000);
- script>

- <input type="text" />
- <script>
- function starDebounce(fn, delay) {
- let timer = null;
- // 1. 返回新的函数,此时这个函数中的this为绑定的dom对象 => 相当于 inputDom的oninput指向这个函数
- // 2. 接受参数
- return function (...args) {
- if (timer) clearTimeout(timer);
- timer = setTimeout(() => {
- // 3. 绑定this,同时把参数传递给fn
- fn.apply(this, args);
- timer = null;
- }, delay);
- };
- }
- script>
- <script>
- const inputDom = document.querySelector('input');
- let counter = 1;
- inputDom.oninput = starDebounce(function (e) {
- console.log(`发送网络请求 :${counter++} => ${this.value} `, e);
- }, 1000);
- script>

- <input type="text" />
- <button>取消button>
- <script>
- function starDebounce(fn, delay) {
- let timer = null;
- // 1. 返回新的函数,此时这个函数中的this为绑定的dom对象 => 相当于 inputDom的oninput指向这个函数
- // 2. 接受参数
- const _debounce = function (...args) {
- if (timer) clearTimeout(timer);
- timer = setTimeout(() => {
- // 3. 绑定this,同时把参数传递给fn
- fn.apply(this, args);
- timer = null;
- }, delay);
- };
- // 3. 因为函数也是一个对象,所以
- _debounce.cancle = function () {
- if (timer) clearTimeout(timer);
- timer = null;
- };
- // 4. 返回函数
- return _debounce;
- }
- script>
- <script>
- const inputDom = document.querySelector('input');
- let counter = 1;
- const debounceFn = starDebounce(function (e) {
- console.log(`发送网络请求 :${counter++} => ${this.value} `, e);
- }, 1000);
- // 执行
- inputDom.oninput = debounceFn;
-
- // 取消
- const btnDom = document.querySelector('button');
- btnDom.onclick = debounceFn.cancle;
- script>

- <input type="text" />
- <button>取消button>
- <script>
- function starDebounce(fn, delay, immediate = false) {
- let timer = null;
- // 1. 是否是第一次执行
- let isInvoke = true;
- const _debounce = function (...args) {
- if (timer) clearTimeout(timer);
-
- // 2. 第一次操作不需要延迟
- if (immediate && isInvoke) {
- fn.apply(this, args);
- timer = null;
- isInvoke = false;
- return;
- }
-
- timer = setTimeout(() => {
- fn.apply(this, args);
- timer = null;
- // 3. 执行完后恢复
- isInvoke = true;
- }, delay);
- };
- _debounce.cancle = function () {
- if (timer) clearTimeout(timer);
- timer = null;
- // 3. 执行完后恢复
- isInvoke = true;
- };
- return _debounce;
- }
- script>
- <script>
- const inputDom = document.querySelector('input');
- let counter = 1;
- const debounceFn = starDebounce(
- function (e) {
- console.log(`发送网络请求 :${counter++} => ${this.value} `, e);
- },
- 1000,
- true
- );
- // 执行
- inputDom.oninput = debounceFn;
-
- // 取消
- const btnDom = document.querySelector('button');
- btnDom.onclick = debounceFn.cancle;
- script>

- <input type="text" />
- <button>取消button>
- <script>
- function starDebounce(fn, delay, immediate = false) {
- let timer = null;
- let isInvoke = true;
- const _debounce = function (...args) {
- // 1. 因为有延迟,使用promise
- return new Promise((resolve, reject) => {
- try {
- let res = null;
- if (timer) clearTimeout(timer);
- // 2. 第一次操作不需要延迟
- if (immediate && isInvoke) {
- // 2. 接受函数的返回值
- res = fn.apply(this, args);
- // 3. 传递出去
- resolve(res);
- timer = null;
- isInvoke = false;
- return;
- }
-
- timer = setTimeout(() => {
- res = fn.apply(this, args);
- // 3. 传递出去
- resolve(res);
- timer = null;
- // 3. 执行完后恢复
- isInvoke = true;
- }, delay);
- } catch (error) {
- reject(error);
- }
- });
- };
- _debounce.cancle = function () {
- if (timer) clearTimeout(timer);
- timer = null;
- // 3. 执行完后恢复
- isInvoke = true;
- };
- return _debounce;
- }
- script>
- <script>
- const debounceFn = starDebounce(function (name, text, age) {
- console.log(name, text, age);
- return '执行完了';
- }, 1000);
- // 4. 传递参数并接受返回值
- debounceFn('coder', 'star', 18).then((res) => {
- console.log(res);
- });
- // 取消
- const btnDom = document.querySelector('button');
- btnDom.onclick = debounceFn.cancle;
- script>
- function starDebounce(fn, delay, immediate = false) {
- let timer = null;
- let isInvoke = true;
-
- const _debounce = function (...args) {
- return new Promise((resolve, reject) => {
- try {
- let res = null;
- if (timer) clearTimeout(timer);
- if (immediate && isInvoke) {
- res = fn.apply(this, args);
- resolve(res);
- timer = null;
- isInvoke = false;
- return;
- }
-
- timer = setTimeout(() => {
- res = fn.apply(this, args);
- resolve(res);
- timer = null;
- isInvoke = true;
- }, delay);
- } catch (error) {
- reject(error);
- }
- });
- };
- _debounce.cancle = function () {
- if (timer) clearTimeout(timer);
- timer = null;
- isInvoke = true;
- };
- return _debounce;
- }

- <input type="text" />
-
-
- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.4/underscore-umd-min.js">script>
-
- <script>
- // 2.获取input元素
- const inputEl = document.querySelector('input');
-
- // 3.节流处理代码
- let counter = 1;
- inputEl.oninput = _.throttle(function () {
- console.log(`发送网络请求${counter++}:`, this.value);
- }, 1000);
- script>

- <input type="text" />
-
- <script>
- /**
- * fn : 传入的函数
- * interval : 间隔的请求时间
- * 公式 : 等待时间 = 间隔时间 - ( 当前时间 - 开始时间 ) => interval - ( nowTime - startTime )
- *
- * 等待时间 <= 0 即可执行函数
- */
- function starThrottle(fn, interval) {
- // 1. 获取开始时间,赋初始值为0
- let startTime = 0;
- function throttle() {
- // 2. 获取当前时间
- const nowTime = new Date().getTime();
- // 3. 计算等待时间
- const waitTime = interval - (nowTime - startTime);
- // 4. 判断是否执行函数,第一次会默认执行
- if (waitTime <= 0) {
- fn();
- // 5.一旦执行完后,把当前时间赋值给开始时间
- startTime = nowTime;
- }
- }
- return throttle;
- }
- script>
-
- <script>
- // 2.获取input元素
- const inputEl = document.querySelector('input');
-
- // 3.节流处理代码
- let counter = 1;
- inputEl.oninput = starThrottle(function () {
- console.log(`发送网络请求${counter++}:`, this.value);
- }, 2000);
- script>

- <input type="text" />
-
- <script>
- function starThrottle(fn, interval) {
- let startTime = 0;
- // 节流函数接受参数
- function throttle(...args) {
- const nowTime = new Date().getTime();
- const waitTime = interval - (nowTime - startTime);
- if (waitTime <= 0) {
- // 相当于 inputEl 直接调用该函数,所以this指向 inputEl
- // 把参数传给函数,即可在回调函数中拿到
- fn.apply(this, args);
- startTime = nowTime;
- }
- }
- return throttle;
- }
- script>
-
- <script>
- // 2.获取input元素
- const inputEl = document.querySelector('input');
-
- // 3.节流处理代码
- let counter = 1;
- inputEl.oninput = starThrottle(function (e) {
- // 使用
- console.log(`发送网络请求${counter++}:`, this.value, e);
- }, 2000);
- script>

- <input type="text" />
-
- <script>
- /**
- * fn : 传入的函数
- * interval : 间隔时间
- * immediate : 第一次是否执行,默认是马上执行的
- */
- function starThrottle(fn, interval, immediate = true) {
- let startTime = 0;
- function throttle(...args) {
- const nowTime = new Date().getTime();
- // 如果immediate为false,且 开始时间为0时
- // 把当前时间赋值给开始时间,这样使得第一次不会执行
- if (!immediate && startTime === 0) {
- startTime = nowTime;
- }
- const waitTime = interval - (nowTime - startTime);
- if (waitTime <= 0) {
- fn.apply(this, args);
- startTime = nowTime;
- }
- }
- return throttle;
- }
- script>
-
- <script>
- // 2.获取input元素
- const inputEl = document.querySelector('input');
-
- // 3.节流处理代码
- let counter = 1;
- inputEl.oninput = starThrottle(
- function (e) {
- // 使用
- console.log(`发送网络请求${counter++}:`, this.value, e);
- },
- 1000,
- false
- );
- script>

- function starThrottle(fn, interval, immediate = true) {
- let startTime = 0;
- function throttle(...args) {
- return new Promise((resolve, reject) => {
- try {
- const nowTime = new Date().getTime();
- // 如果immediate为false,且 开始时间为0时
- // 把当前时间赋值给开始时间,这样使得第一次不会执行
- if (!immediate && startTime === 0) {
- startTime = nowTime;
- }
- const waitTime = interval - (nowTime - startTime);
- if (waitTime <= 0) {
- //
- const res = fn.apply(this, args);
- resolve(res);
- startTime = nowTime;
- }
- } catch (error) {
- reject(error);
- }
- });
- }
- return throttle;
- }
-
- <script>
- // 3.节流处理代码
- let counter = 1;
- const throttleFn = starThrottle(function (...e) {
- // 使用
- console.log(`发送网络请求${counter++}:`, e);
- return '无敌 🦖 战神';
- }, 1000);
- throttleFn('inside', 'args').then((res) => {
- console.log('返回值:', res);
- });
- script>
- function starThrottle(fn, interval, immediate = true) {
- let startTime = 0;
- function throttle(...args) {
- return new Promise((resolve, reject) => {
- try {
- const nowTime = new Date().getTime();
- if (!immediate && startTime === 0) {
- startTime = nowTime;
- }
- const waitTime = interval - (nowTime - startTime);
- if (waitTime <= 0) {
- //
- const res = fn.apply(this, args);
- resolve(res);
- startTime = nowTime;
- }
- } catch (error) {
- reject(error);
- }
- });
- }
- return throttle;
- }
- // 直接最终版本
-
- /**
- * fn : 传入的函数
- * interval : 间隔时间
- * 不方便设置第一次马上执行
- */
- function starThrottle(fn, interval) {
- // 1. 是否锁住
- let locked = false;
- function throttle(...args) {
- return new Promise((resolve, reject) => {
- try {
- // 2. 判断是否锁住,如果锁住直接返回
- if (locked) return true;
- // 3. 进来后直接锁住
- locked = true;
- // 4. 开启定时器
- setTimeout(() => {
- const res = fn.apply(this, args);
- resolve(res);
- // 5. 执行完后,解锁
- locked = false;
- }, interval);
- } catch (error) {
- reject(error);
- }
- });
- }
- return throttle;
- }