我理解Underscore.js中的
我的问题是,在普通的JavaScript中,使用
debounce
会返回一个函数,该函数将推迟其执行直到等待时间结束。我的问题是,在普通的JavaScript中,使用
debounce
是否比使用常规的setTimeout
函数有优势? 它们不是都可以起到同样的作用吗?debounce
会返回一个函数,该函数将推迟其执行直到等待时间结束。debounce
是否比使用常规的setTimeout
函数有优势? 它们不是都可以起到同样的作用吗?它们非常不同,用途完全不同。
_.debounce
返回一个function
,setTimeout
返回一个id
,您可以使用该ID取消timeOut。
无论您调用由_.debounce返回的函数多少次,在给定的时间范围内它都只会运行一次。
var log_once = _.debounce(log, 5000);
function log() {
console.log('prints');
}
log_once();
log_once();
log_once();
log_once();
log_once();
var id = setTimeout(function() {
console.log('hello');
}, 3000);
clearTimeout(id);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
setTimeout
只是等待n
毫秒,然后调用提供的函数。debounce
返回一个函数,只有在上次调用该函数之后的n
毫秒后才调用回调函数。
差别很大。防抖/节流(它们不是同一回事)函数经常用于减少用户输入导致的函数调用量。想象一下自动完成/类型提示字段。您可能会在每次按键时进行ajax请求,但这可能会变得很重,因此您可以将函数防抖,以便它仅在上一个按键之后的200毫秒后触发。
您可以在此处查看文档:https://lodash.com/docs#debounce
你也可以在Vanilla JavaScript中实现自己的防抖函数。一篇被广泛引用的文章是David Walsh关于使用underscore进行函数防抖的文章,其中包括underscore在他们的实现中使用的源代码:
// 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.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Debounce函数用作你想要调用的实际函数的生成器,这样状态就可以在闭包内进行持久化,就像这样:
// example function
let sayHello = (name) => console.log(`Hi ${name}`)
// generate a debounced version with a min time between calls of 2 seconds
let sayHelloDebounced = debounce(sayHello, 2000)
// call however you want
sayHelloDebounced('David')
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
let sayHello = (name) => console.log(`Hi ${name}`)
let sayHelloDebounced = debounce(sayHello, 2000)
sayHelloDebounced('David')
sayHelloDebounced('David')
sayHelloDebounced('David')
let timer;
function setTimer(){
clearTimeout(timer);
timer = setTimeout(() => console.log("here"), 1000);
};
setTimer();
setTimer();
setTimer();
setTimer();
// here