underscore.js供应了许多很有效的函数,本日想说说个中的两个。这两个函数都用于限定函数的实行。
debounce
在诠释这个函数前,我们先从一个例子看下这个函数的运用场景。假定我们网站有个搜刮框,用户输入文本我们会自动遐想匹配出一些效果供用户挑选。我们能够起首想到的做法就是监听keypress事宜,然后异步去查询效果。这个要领自身是没错的,然则假如用户疾速的输入了一连串的字符,假定是10个字符,那末就会在霎时触发了10次的要求,这无疑不是我们想要的。我们想要的是用户住手输入的时刻才去触发查询的要求,这时刻函数防抖能够帮到我们。
函数防抖就是让某个函数在上一次实行后,满足守候某个时候内不再触发此函数后再实行,而在这个守候时候内再次触发此函数,守候时候会从新盘算。
我们先看下underscore.js里相干函数的定义:
_.debounce(function, wait, [immediate])
javascript
// Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the // leading edge, instead of the trailing. _.debounce = function(func, wait, immediate) { var timeout, args, context, timestamp, result; var later = function() { var last = _.now() - timestamp; if (last < wait && last >= 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) { result = func.apply(context, args); if (!timeout) context = args = null; } } }; return function() { context = this; args = arguments; timestamp = _.now(); var callNow = immediate && !timeout; if (!timeout) timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); context = args = null; } return result; }; };
参数function是须要举行函数防抖的函数;参数wait则是须要守候的时候,单元为毫秒;immediate参数假如为true,则debounce函数会在挪用时马上实行一次function,而不须要比及wait这个时候后,比方防备点击提交按钮时的屡次点击就能够运用这个参数。
所以,上面谁人场景,我们能够这么处置惩罚:
javascript
function query() { //举行异步挪用查询 } var lazyQuery = _.debounce(query, 300); $('#search').keypress(lazyQuery);
throttle
我们网站常常会有如许的需求,就是转动浏览器转动条的时刻,更新页面上的某些规划内容或许去挪用背景的某接口查询内容。一样的,假如不对函数挪用的频次加以限定的话,那末能够我们转动一次转动条就会发生N次的挪用了。然则此次的状况跟上面的有所不同,我们不是要在每完成守候某个时候后去实行某函数,而是要每距离某个时候去实行某函数,防止函数的过量实行,这个体式格局就叫函数撙节。
一样的,我们看下underscore.js里相干函数的定义:
_.throttle(function, wait, [options])
javascript
// Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. Normally, the throttled function will run // as much as it can, without ever going more than once per `wait` duration; // but if you'd like to disable the execution on the leading edge, pass // `{leading: false}`. To disable execution on the trailing edge, ditto. _.throttle = function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : _.now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; return function() { var now = _.now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; };
参数function是须要举行函数撙节的函数;参数wait则是函数实行的时候距离,单元是毫秒。option有两个选项,throttle第一次挪用时默许会马上实行一次function,假如传入{leading: false},则第一次挪用时不实行function。{trailing: false}参数则示意制止末了那一次耽误的挪用。详细能够看源码举行明白。
所以,在转动转动条的场景,我们能够这么做:
javascript
function handleScroll() { //举行转动时的相干处置惩罚 } var throttled = _.throttle(handleScroll, 100); $(window).scroll(throttled);
参考
http://underscorejs.org/#debounce
http://underscorejs.org/#throttle