javascript - 了解 debounce 函数逻辑流程,特别是对于 Event 对象 - (...args) 从哪里获取它的值?
问题描述
我正在学习 Javascript 课程并使用以下代码。我几乎了解所有内容,但我在努力遵循和理解代码中的逻辑流程,特别是对于事件对象,我想确保在继续之前我对此非常清楚。
有同样困惑的其他人在这里提出了几乎完全相同的问题,但不幸的是我无法理解任何答案。
到目前为止,这是我所理解的:
一个键被按下 ->debounce
函数返回(并运行)参数func
和delay
. func
传入的参数是onInput
这种情况下的函数,(据我了解,它会在触发时自动(通过 Javascript)返回一个事件对象addEventListener
)。
但是,onInput
它嵌套在debounce
函数内部运行,func.apply(null, args);
所以我对按下键时如何创建事件对象并通过代码流传递感到困惑?
我的主要问题是,如何或从何处return (...args)
获取debounce
其传播参数?
debounce
在这种情况下,函数不会传递事件对象吗onInput
?如果是这样,如何onInput
访问事件对象?
这是代码:
const fetchData = async (searchTerm) => {
const response = await axios.get('http://www.omdbapi.com/', {
params: {
apikey: '6459bge8',
s: searchTerm
}
});
console.log(response.data);
};
const input = document.querySelector('input');
const debounce = (func, delay) => {
let timeoutId;
//Where is ...args getting it's values from?
return (...args) => {
console.log(args);
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
func.apply(null, args);
}, delay);
};
};
const onInput = (evt) => {
fetchData(evt.target.value);
};
input.addEventListener('input', debounce(onInput, 500));
当我像这样注释掉返回函数中的代码时,我也无法理解:
const debounce = (func, delay) => {
let timeoutId;
return (...args) => {
console.log(args);
// if (timeoutId) {
// clearTimeout(timeoutId);
// }
// timeoutId = setTimeout(() => {
// func.apply(null, args);
// }, delay);
};
};
传入的func
永远不会运行,但是当按下一个键时,console.log(args) 仍然显示InputEvents
在控制台中,表明 args 来自其他地方而不是由func.apply(null, args);
?
解决方案
使用您的代码要了解的主要内容是该addEventListener()
函数不负责调用该debounce()
函数。该debounce()
函数在addEventListener
添加到输入元素时调用,而不是在输入事件发生时调用。这是因为调用debounce()
调用函数,将它返回的任何内容作为第二个参数传递给addEventListener()
. 考虑到这一点,您的函数可以重写为:
const inputHandler = debounce(onInput, 500); // debounce returns a function
input.addEventListener('input', inputHandler); // the returned function is used in the addEventListener function
因此,debounce()
当输入发生时调用返回的函数(而不是debounce
函数本身,因为它是在调用 addEventListener() 方法时调用的,这是在解释器遇到这一行时立即调用,而不是在输入发生时)。
在这种情况下,debounce 函数不会传递事件对象而不是 onInput 吗?如果是这样,onInput 如何访问事件对象?
考虑到上述解释,返回的函数 fromdebounce()
是作为第二个参数传递给addEventListener()
. 结果,返回的函数充当回调并传递事件对象,它可以通过 访问...args
。在上面的代码块中,这意味着inputHanlder
当输入事件发生时被 JS 调用时传递事件对象。所以debounce()
永远不会传递事件参数,它是内部返回的函数,它可以访问事件参数。
作为返回的函数(即:代码示例中的内部函数),传递事件对象,它可以通过args
. 然后内部函数onInput
使用事件对象调用/调用函数func.apply(null, args);
。
至于您的最后一个示例,该func
函数永远不会运行,因为它永远不会在任何地方调用。它被传递到您的函数中,但它永远不会被调用/执行(与第一个示例中它确实被调用 using不同.apply()
)。不过 InputEvent 仍然会被记录,因为它addEventListener()
是在输入发生时调用返回的回调的原因。结果,内部函数仍然可以访问事件对象。
推荐阅读
- linux - 如何在 VSCODE 上使用 root 权限调试您的应用程序?
- java - 关于附件部分的问题。附件是按什么顺序来的?
- python - 将注释作为基本事实与图像一起提供给模型
- google-kubernetes-engine - GKE 集群的 Stackdriver 错误报告
- javascript - 如何汇总值并从外部 API 中删除重复项
- python - 使用 Python 在 Jenkins 上运行行为测试
- angular - 在功能模块中从同级路由导航到同级子路由时出错
- python - 将 5 级字典(以 pd.Series 作为值转换为 pandas DataFrame
- python - 如何创建一个 for 循环来检查列表元素与字典中包含的列表元素?
- mysql - 查找所有收入超过其公司所有员工平均工资的员工