从事 fetch/axios/debounce 个项目

Working on a fetch/axios/debounce project

我刚刚完成了由名为 Colt Steele / Steven Grider 的讲师在 Udemy 上在线 class 的大部分教程,并且面临项目混乱。我在一个项目中,我被介绍制作一个 "debounce" 函数来不执行 api 调用 everytime 我在输入栏中输入一个键。但是,我不理解去抖功能背后的逻辑(例如,return 之后的传播(...args)和它提供的整体 "shield"。我想知道是否有人可以提供帮助用更清楚的方式解释一下?谢谢!

const fetchData = async (searchTerm) =>{ //mark the function as async
    const response = await axios.get('http://www.omdbapi.com/',{ //await to get response from async, calls the web portal
        params: {
            apikey: 'xxx',

            s: 'avengers'

        },


    }); 
    console.log(response.data)
};

const input = document.querySelector('input');



const debounce = (func) => {
    let timeoutId;
    return (...args) => {
        if(timeoutId){
            clearTimeout(timeoutId);
        }
        timeoutId = setTimeout(()=>{
            func.apply(null, args);
        },1000)
    };
};

const onInput = event =>{
    fetchData(event.target.value);
}

input.addEventListener('input', debounce(onInput))

我一步一步解释你的代码,如果你喜欢在codesanbox中看到它here is a link

const input = document.querySelector("input");

/*High Order Function
a higher-order function is a function that does at least one of the following:

* takes one or more functions as arguments (i.e. procedural parameters),
* returns a function as its result.

Closure
Here you will see info about that js topic 
https://levelup.gitconnected.com/using-closures-in-javascript-to-create-private-variables-c0b358757fe0
*/

// this is a high order function
const debounce = func => {
  /* this variable save the setTimeout id and the reason why it 
  will be persist is because this is the this is a closure and for that, 
  the returned function will remember their execution context 
  and therefore the value of timeoutId and calledNTimes*/
  let timeoutId;
  let calledNTimes = 0;

  /* this args parameter comes from the function passed as 
  argument to debounce, and their value is the event from the addEventListener
  function, you can call args as you like but normaly you will 
  find it with this name.


  you use the spread operator to the argument from addEventListener as an
  array, because func.apply accept an array of args */
  return (...args) => {
    console.log((calledNTimes += 1), timeoutId);
    console.log("args", args);

    /* After the first debounce called, the setTimeout will be 
    clear while the user is typing, or until it is executed */
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    timeoutId = setTimeout(() => {
      /* with func apply method you execute the function with 
      the args comming from the original call, and this args
      value is the event from the addEventListener */

      func.apply(null, args);
    }, 1000);
  };
};

const onInput = event => {
  fetchData(event.target.value);
};

/* some interesting thing is that as you are executing debounce here 
(because you add the parentesis), you can see the second parameter of
addEventListener as the anonymous function returned by debounce, I mean
to say:

(...args) => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    timeoutId = setTimeout(() => {
      func.apply(null, args);
    }, 1000);

but if you pass literally the function, you will lose the closure feature.
*/

input.addEventListener("input", debounce(onInput));

/* if you console.log the params with and without the spread operator you will 
see the difference.*/
function testFunction(...params) {
  console.log(params);
}

input.addEventListener("input", testFunction);