javascript - 如何使用返回另一个函数的函数?
问题描述
关于返回其他函数的函数如何工作,我从根本上不了解。我有以下油门功能,我使用它来确保不会经常发送命令。它已经完全从 StackOverflow 中提取出来了,我没有写这个。
// 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.
function throttle(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function () {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function () {
var now = Date.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;
};
};
我把它绑在一个范围滑块上。这种超基本的解释完美地工作
volSlider = document.querySelector("#slider-vol");
volSlider.oninput = throttle(sendVolumeMessage, 100);
function sendVolumeMessage() {
console.log(`Throttled Volume ${volSlider.value}`);
}
问题是我也想用那个滑块做非节流的事情。以下不起作用
volSlider = document.querySelector("#slider-vol");
volSlider.oninput = setVolume();
function setVolume() {
return function () {
console.log(`Volume ${volSlider.value}`);
throttle(sendVolumeMessage, 100);
}
}
function sendVolumeMessage() {
console.log(`Throttled Volume ${volSlider.value}`);
}
控制台日志显示“Volume 30”或任何数字,但不显示 Throttled Volume。关于函数内部传递函数的工作原理,我不了解什么?显然,我实际上并没有在我的 setVolume 函数中调用油门函数,但我终其一生都无法弄清楚原因。
解决方案
存储油门并调用它
volSlider = document.querySelector("#slider-vol");
volSlider.oninput = setVolume();
function setVolume() {
const fnc = throttle(sendVolumeMessage, 100);
return function () {
console.log(`Volume ${volSlider.value}`);
fnc();
}
}
function sendVolumeMessage() {
console.log(`Throttled Volume ${volSlider.value}`);
}
或使用 addEventListener 添加两个单独的事件
function otherFunction () {
console.log(new Date());
}
volSlider = document.querySelector("#slider-vol");
volSlider.addEventListener('input', throttle(sendVolumeMessage, 100));
volSlider.addEventListener('input', otherFunction);
推荐阅读
- ruby-on-rails - 是否可以在生产环境中使用 Rails、Webpacker 将 Vue.js 组件挂载到 DOM 上?
- python-3.x - 如何使用 Pandas 作为函数将数值重新分类到新的分组中,没有条件限制
- ruby-on-rails - Rails 和 Rspec 单元测试静态方法
- ios - iOS PDFKit - 宽度问题
- javascript - HTML 防盗
- python - 使用模拟数据进行深度学习
- python - 如何随机化 if/elif 语句的顺序?
- drools - Drools 为 StatelessKieSession 的列表输入中的每个项目触发一个规则
- sql - 重叠日期范围总结
- javascript - A-Frame:以编程方式拍摄全景截图