Marc Fletcher
Marc Fletcher

Reputation: 1082

Vue.js – why is my debounce function not working with arrow function

Here is my debounce function:

function debounce(fn, wait = 1500) {
  let timeout;
  return function (...args) {
    if (timeout) clearTimeout(timeout);
    let context = this;
    timeout = setTimeout(function () {
      fn.apply(context, ...args);
    }, wait);
  };
}

Here is my method in the component:

methods: {
    onKeyUp() {
      if(this.q.length) this.isLoading = true; // show loading spinner
      return debounce(() => this.querySearch())()
    },

So I have to execute the debounce call with an extra set of () which makes sense, because debounce returns a function. Now, if I change it to this:

methods: {
    onKeyUp: debounce(function() { 
       this.querySearch()
    })

I don't understand why this works – debounce returns a function. I would expect when onKeyUp is triggered, it would run debounce - which just returns a function, without ever executing it. Does it implicitly execute the returned function with this syntax? Why?

Also, why does it need to be a non-arrow function in the second example? I know in the first example you want an arrow fn because you want this to point to the component context, but im unclear why using this key-value syntax breaks that down here.

Upvotes: 0

Views: 695

Answers (1)

Estus Flask
Estus Flask

Reputation: 222750

debounce(function() {...}) is an expression. onKeyUp is assigned to the result of its evaluation. The result of debounce call is debounced function, so is onKeyUp.

I would expect when onKeyUp is triggered, it would run debounce

This isn't how JavaScript works. Given var foo = 1 + 1, 1 + 1 is eagerly evaluated to 2, not at the time when foo variable is accessed. The only possibility for the code to be lazily evaluated is to wrap it inside a function. This is what happens in case of debounce. The code inside function() {...} is called after a delay when debounced function is called. debounce itself is called when it's called.

Also, why does it need to be a non-arrow function in the second example

Because this is the only way the function can get component instance as this. Since arrows don't have their own context, this would refer to outer context with an arrow, which is module context in which the component is defined:

onKeyUp: debounce(() => {...})

and

onKeyUp: () => {...}

Upvotes: 4

Related Questions