javascript 中的去抖实时搜索未执行关闭
Debounced live search in javascript not executing closure
下面的代码模拟通过 debounce function 执行实时搜索(替换为控制台输出)。
debounce函数被调用,但是传递的liveSearch
函数没有被调用。我猜是因为 debounce
returns 一个没有被执行的函数。
如何调用 liveSearch
使其真正去抖动?
var MySearch = (function($) {
var $search = $('.search'),
searchDelay = 500,
keysToIgnore = [8, 16, 17, 18, 27, 32, 37, 38, 39, 40, 91, 191, 220]; // space, esc, bkspc, ctrl, alt, cmd, arrows, /\
function init() {
$search.on('keyup', function(e) {
if (keysToIgnore.indexOf(e.keyCode) == -1) {
// FIXME: this isn't actually executing the passed liveSearch fn
debounce(liveSearch, searchDelay);
// This executes liveSearch, but doesnt debounce
// debounce(liveSearch, searchDelay)();
}
});
}
function liveSearch() {
console.log("searching:", $search.val());
}
// Remy's debounce func:
// https://remysharp.com/2010/07/21/throttling-function-calls
function debounce(fn, delay) {
console.log("debouncing for", delay);
var timer = null;
return function () {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
return {
init: init
};
}(jQuery));
jQuery(function() {
MySearch.init();
});
debounce
的每次调用都使用 timer
变量创建自己的闭包。因此 debounce
函数被设计为被调用一次,而 returns 一个函数应该被调用而不是 liveSearch
:
function init() {
var debouncedLiveSearch = debounce(liveSearch, searchDelay);
$search.on('keyup', function(e) {
if (keysToIgnore.indexOf(e.keyCode) == -1) {
debouncedLiveSearch();
}
});
}
下面的代码模拟通过 debounce function 执行实时搜索(替换为控制台输出)。
debounce函数被调用,但是传递的liveSearch
函数没有被调用。我猜是因为 debounce
returns 一个没有被执行的函数。
如何调用 liveSearch
使其真正去抖动?
var MySearch = (function($) {
var $search = $('.search'),
searchDelay = 500,
keysToIgnore = [8, 16, 17, 18, 27, 32, 37, 38, 39, 40, 91, 191, 220]; // space, esc, bkspc, ctrl, alt, cmd, arrows, /\
function init() {
$search.on('keyup', function(e) {
if (keysToIgnore.indexOf(e.keyCode) == -1) {
// FIXME: this isn't actually executing the passed liveSearch fn
debounce(liveSearch, searchDelay);
// This executes liveSearch, but doesnt debounce
// debounce(liveSearch, searchDelay)();
}
});
}
function liveSearch() {
console.log("searching:", $search.val());
}
// Remy's debounce func:
// https://remysharp.com/2010/07/21/throttling-function-calls
function debounce(fn, delay) {
console.log("debouncing for", delay);
var timer = null;
return function () {
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
return {
init: init
};
}(jQuery));
jQuery(function() {
MySearch.init();
});
debounce
的每次调用都使用 timer
变量创建自己的闭包。因此 debounce
函数被设计为被调用一次,而 returns 一个函数应该被调用而不是 liveSearch
:
function init() {
var debouncedLiveSearch = debounce(liveSearch, searchDelay);
$search.on('keyup', function(e) {
if (keysToIgnore.indexOf(e.keyCode) == -1) {
debouncedLiveSearch();
}
});
}