函数防抖debounce封装 + npm包 + jasmine单元测试

debounce

分析

  • 函数防抖需求原因
  • 实现原理
  • 封装,优化
  • 发布,成为npm包

正常情况下,一个input搜索框只要输入信息,就会调用ajax请求
公用代码:

<style>
    #i {
         width: 300px;
         height: 28px;
         margin-top:50px;
         margin-left:100px;
       }
</style>
<input type="text" id="i">
const i = document.getElementById('i');
const c = document.getElementById('content');

一、正常input搜索框触发请求

实时ajax请求
    i.oninput = () => {
      console.log(i.value);
      ajax(i.value);
    }
    function ajax(e) {
      console.log(e)
    }

二、函数防抖debounce

  • 正常的input搜索框,每次输入就触发一次ajax请求,多了很多不必要的性能消耗
  • 用户在搜索框的中文打字状态中,也同样会触发ajax事件


    中文输入法

三、debounce思路

设定input输入后一定时间后才会触发事件,减少性能消耗

即延迟处理函数,如果设定的时间到来之前,又一次触发了事件,就清除上一次的定时器

  • input输入后,超过300mssetTimeout发送请求,调用函数,定时器变量timer设为null
  • 每次事件触发前先判断上一次的定时器timer是否是null

具体代码

let count = 0;
    let timer;
    i.oninput = () => {
        if(timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            ajax();
            timer = null;
        }, 300);
    }
    function ajax() {
        console.log(`ajax${++count}`);
    }
debounce函数防抖

四、优化封装debounce

  • 需求:我们想让timer成为一个方法里内部变量,而不是在input事件外部单独定义变量
  • 方法: 闭包实现封装,闭包就是能够读取其他函数内部变量的函数
  • 延迟的时间请求的函数作为参数参入封装后的参数

代码如下

let count = 0;
    const debounce = debounceWrapper(ajax, 300);
    i.oninput = () => {
        debounce();
    }

    function debounceWrapper(fn, debounceTime = 300 ) {
        let timer; 
         return function() {
            if(timer) {
            clearTimeout(timer);
            }
            timer = setTimeout(() => {
                fn();
                timer = null;
            }, debounceTime);
         }
    }
    function ajax() {
        console.log(`ajax${++count}`);
    }

五、jasmine 单元测试

npm install jasmine --save-dev // 安装jasmine dev环境下单元测试包

// package.json 修改test的文件目录
 "scripts": {
    "test": "node node_modules/jasmine/bin/jasmine test/test.js"
  },
 "main": "src/index.js", // 入口文件

// 跑单元测试
npm run test
var debounceTransfer = require('..')

describe('debounce test case', function () {
    var fn
    var debounce
    beforeEach(function () {
        fn = jasmine.createSpy('fn')
        debounce = debounceTransfer(fn, 500)
        jasmine.clock().install()
    })

    afterEach(function () {
        jasmine.clock().uninstall()
    })
    
    it('test case1', function () {
        debounce()
        jasmine.clock().tick(500)
        expect(fn).toHaveBeenCalledTimes(1)
    })

    it('test case2', function () {
        debounce()
        debounce()
        jasmine.clock().tick(500)
        expect(fn).toHaveBeenCalledTimes(1)
    })

})
单元测试跑通

下载

npm 下载
github下载
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,074评论 3 119
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 28,473评论 1 45
  • 几年前和同事们一起参加共创式教练(Co-active Coaching)培训,其中有一个模块就是探索发现每个人的人...
    心田雨露27阅读 1,517评论 0 2
  • 文/A 幸运点 无边无界有源头,细水东来夜未休。 万里江陵升旭日,千斑帆影点清洲。 一轮明月虚空煮,几盏零星瀚海收...
    A幸运点阅读 3,034评论 28 20
  • 第九章 对无关紧要的人:巧用利益的引诱 利益捆绑法则 我们在一条船上,船就会稳固;反之,总会有人过来把船打翻。 所...
    君为jw阅读 3,434评论 0 0

友情链接更多精彩内容