Работа над проектом fetch / axios / debounce - PullRequest
0 голосов
/ 23 апреля 2020

Я только что закончил большинство уроков онлайн-урока по Удеми от инструкторов по имени Кольт Стил / Стивен Гридер, и столкнулся с путаницей проекта. Я нахожусь в проекте, где я был представлен для создания функции "debounce", чтобы не оправдывать вызов API. Каждый раз, когда я вводил клавишу внутри панели ввода. Однако я не понимаю логики c, стоящие за функцией debounce (например, спред (... args) сразу после возврата и общий «щит», который он предлагает. Мне интересно, может ли кто-нибудь помочь объяснить это в яснее? Спасибо!

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))

1 Ответ

1 голос
/ 23 апреля 2020

Я объясню ваш код шаг за шагом, если вы хотите увидеть его в codesanbox вот ссылка .

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);
...