函数节流(js的问题)

简介: 函数节流(js的问题)

函数节流也用到了高阶函数的知识,因为比较重要,所以单开了一个标题。

javascript中的函数在大多数情况下都是由用户主动调用触发的,除非是函数本身的实现不合理。但是在一些少数情况下,函数可能被很频繁的调用,而造成大的性能问题。

(1)函数被频繁调用的场景

1.window.onresize事件
2.mousemove事件
3.上传进度

(2)函数节流的原理

解决函数触发频率太高的问题,需要我们按照时间段来忽略一些事件请求。

(3)函数节流的代码实现

详情可以参考

Underscore.js#throttle

Underscore.js#debounce

简单实现:


将即将被执行的函数用steTimeout延时一段时间执行。如果该次延时执行还没有完成,就忽略掉接下来调用该函数的请求。

var throttle = function ( fn, interval ) {
        var __self = fn, // 保存需要被延迟执行的函数引用
        timer, // 定时器
        firstTime = true; // 是否是第一次调用
        return function () {
            var args = arguments,
            __me = this;
            if ( firstTime ) { // 如果是第一次调用,不需延迟执行
                __self.apply(__me, args);
                return firstTime = false;
            }
            if ( timer ) { // 如果定时器还在,说明前一次延迟执行还没有完成
                return false;
 
            timer = setTimeout(function () { // 延迟一段时间执行
                clearTimeout(timer);
                timer = null;
                __self.apply(__me, args);
            }, interval || 500 );
        };
    };
 
 
    window.onresize = throttle(function(){
        console.log( 1 );
    }, 500 );

另一种实现函数节流的方法-分时函数

某些函数确实是用户主动调用的,但是因为一些客观的原因,这些函数会严重的影响页面的性能。

一个例子就是创建QQ好友列表。如果一个好友列表用一个节点表示,当我们在页面中渲染这个列表的时候,可能要一次性的网页面中创建成百上千个节点。

var ary = [];
for ( var i = 1; i <= 1000; i++ ){
    ary.push( i ); // 假设ary 装载了1000 个好友的数据
};
 
var renderFriendList = function( data ){
    for ( var i = 0, l = data.length; i < l; i++ ){
        var div = document.createElement( 'div' );
        div.innerHTML = i;
        document.body.appendChild( div );
    }
};
 
renderFriendList( ary );

在短时间内网页面中大量添加DOM节点显然也会让浏览器吃不消。

这个问题的解决方案之一是下面的timeChunk函数:让创建节点的工作分批进行

//第一个参数是创建节点时需要的数据,第二个参数封装了创建节点逻辑的函数,第三个参数表示每一批创建节点的数量。
var timeChunk = function( ary, fn, count ){
    var obj,
    t;
    var len = ary.length;
    var start = function(){
        for ( var i = 0; i < Math.min( count || 1, ary.length ); i++ ){
            var obj = ary.shift();
            fn( obj );
        }
    };
    return function(){
        t = setInterval(function(){
        if ( ary.length === 0 ){ // 如果全部节点都已经被创建好
            return clearInterval( t );
        }
        start();
        }, 200 ); // 分批执行的时间间隔,也可以用参数的形式传入
    };
};
 
var ary = [];
for ( var i = 1; i <= 1000; i++ ){
    ary.push( i );
};
var renderFriendList = timeChunk( ary, function( n ){
    var div = document.createElement( 'div' );
    div.innerHTML = n;
    document.body.appendChild( div );
}, 8 );
renderFriendList();


相关文章
|
JavaScript
VUE3(十)生命周期及钩子函数
Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
6456 0
VUE3(十)生命周期及钩子函数
|
4月前
|
人工智能 JavaScript 前端开发
理解 JavaScript 中的节流和防抖:实现 `throttle` 和 `debounce` 函数
节流(throttle)是指在一定时间间隔内只执行一次函数,常用于控制高频事件触发频率,如滚动、窗口调整等。本文介绍其实现原理与代码示例。
190 0
|
应用服务中间件 nginx C语言
3分钟教你搞定 nginx 编译安装报错:error: the HTTP rewrite module requires the PCRE library.
3分钟教你搞定 nginx 编译安装报错:error: the HTTP rewrite module requires the PCRE library.
5057 0
3分钟教你搞定 nginx 编译安装报错:error: the HTTP rewrite module requires the PCRE library.
|
前端开发 JavaScript
用JavaScript 实现一个简单的 Promise 并打印结果
用 JavaScript 实现一个简单的 Promise 并打印结果
|
JavaScript
typeScript基础(3)_ts函数默认值和可选参数
本文介绍了在TypeScript中如何使用函数的默认值和可选参数。展示了如何为函数参数指定默认值,使得在调用函数时可以省略某些参数,以及如何定义可选参数。
930 2
|
JavaScript API
Vue3基础(24)___vue3中不再支持filters
Vue 3中不再支持filters(过滤器)
242 2
|
11月前
|
机器学习/深度学习 运维 数据可视化
Python时间序列分析:使用TSFresh进行自动化特征提取
TSFresh 是一个专门用于时间序列数据特征自动提取的框架,支持分类、回归和异常检测等机器学习任务。它通过自动化特征工程流程,处理数百个统计特征(如均值、方差、自相关性等),并通过假设检验筛选显著特征,提升分析效率。TSFresh 支持单变量和多变量时间序列数据,能够与 scikit-learn 等库无缝集成,适用于大规模时间序列数据的特征提取与模型训练。其工作流程包括数据格式转换、特征提取和选择,并提供可视化工具帮助理解特征分布及与目标变量的关系。
806 16
Python时间序列分析:使用TSFresh进行自动化特征提取
|
开发框架 前端开发 JavaScript
利用Spire.Pdf实现PDF添加印章的操作
利用Spire.Pdf实现PDF添加印章的操作
|
JavaScript 前端开发 UED
js的节流
js的节流
254 0
|
算法 JavaScript 前端开发
深入了解Vue2和Vue3的Diff算法差异!
总的来说,Vue3在Diff算法上的优化体现了更智能的静态内容处理、更高效的动态内容更新以及更灵活的内部结构。这些优化使得Vue3在运行时性能上有了显著的提升,尤其是在大型应用和复杂界面的场景下。通过不断地技术迭代和优化,Vue3为开发者提供了更高效、更易用的前端开发体验。
1082 6