首页 > 解决方案 > 了解 debounce 函数逻辑流程,特别是对于 Event 对象 - (...args) 从哪里获取它的值?

问题描述

我正在学习 Javascript 课程并使用以下代码。我几乎了解所有内容,但我在努力遵循和理解代码中的逻辑流程,特别是对于事件对象,我想确保在继续之前我对此非常清楚。

有同样困惑的其他人在这里提出了几乎完全相同的问题,但不幸的是我无法理解任何答案。

到目前为止,这是我所理解的:

一个键被按下 ->debounce函数返回(并运行)参数funcdelay. 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);?

标签: javascript

解决方案


使用您的代码要了解的主要内容是该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()是在输入发生时调用返回的回调的原因。结果,内部函数仍然可以访问事件对象。


推荐阅读