函数节流(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();


相关文章
|
6月前
|
JavaScript
JS中防抖和节流的区别是什么
JS中防抖和节流的区别是什么
47 0
|
6月前
|
JavaScript 前端开发 UED
js的节流
js的节流
33 0
|
6月前
|
JavaScript
js-防抖
在浏览器的各种事件中,有一些容易频繁触发的事件,比如scroll、resize、鼠标事件(比如 mousemove、mouseover)、键盘事件(keyup、keydown )等。频繁触发回调导致大量的计算会引发页面抖动甚至卡顿,影响浏览器性能。防抖和节流就是控制事件触发的频率的两种手段。
|
JavaScript UED
JS的节流、防抖
JS的节流、防抖
41 0
|
JavaScript 前端开发
介绍一下js的节流与防抖?
介绍一下js的节流与防抖?
|
JavaScript
JS中防抖和节流
JS中防抖和节流
js-节流
节流的中心思想是:在某段时间内,不管你触发了多少次回调,我都只认第一次,并在计时结束时给予响应,也就是隔一段时间执行一次。
|
JavaScript 前端开发
JS 节流函数的实现
JS 节流函数的实现
162 0
|
JavaScript
JS防抖的实现方法
JS防抖的实现方法