logo

Debounce Function

In the beginning, please check: David Corbacho's article As it gives details over the differences between _.debounce and _.throttle.

Overview

We want to create an application that converts between JSON and YAML and another way around. When we update the JSON part, we need to update YAML content, and the same is applied when updating YAML.

Example:

We are using Simple JavaScript and YAML-JS Library to do the change between JSON and YAML.

JSON to YAML Converting

First, we recive JSON as string from the text editor then we convert it to JSON Object using JSON.parse(). And if the parsing successed we convert the JSON Object to the YAML string as shown below: JSON TO YAML Parsing Function

jsonChangeHandler = (newValue) =>{
  this.setState({json: newValue})
  try{
    const newJson = JSON.parse(newValue);
    const newYaml = YamlJS.dump(newJson);
    this.setState({yaml: newYaml})    
  }catch(e){
    console.log(e);
  }
}

YAML to JSON Converting

We take the string from the code editor and convert it to JSON Object using YAML-js library then we turn the generated JSON Object to string to show it in the editor.

YAML TO JSON Parsing Function

yamlChangeHandler = (newValue) =>{
  this.setState({yaml: newValue})
  try{
    const newJson = YamlJS.load(newValue);
    const newJsonAsString = JSON.stringify(newJson || '', null, 2);
    this.setState({json: newJsonAsString});
  }catch(e){
    console.log(e);
  }
}

Some methods as JSON.parse() and JSON.stringify() have performance impact to our application. Especially when we are doing the converting process on every key down. Moreover, while the user is typing, we won't get valid input from the user until he finishes typing.

Improve Performance using Debouncing.

With the scope of this project, we will be using lodash debounce.

Now, our implementation will be as follow:

JSON TO YAML Parsing Function

  jsonChangeHandler = (newValue) =>{
    this.setState({json: newValue})
    this.covertToYaml(newValue);
  }

  covertToYaml = debounce((jsonString) =>{
     try{
      const newJson = JSON.parse(jsonString);
      const newYaml = YamlJS.dump(newJson);
      this.setState({yaml: newYaml})   
     }catch(e){
       console.log(e);
     } 
  }, 1300)

YAML TO JSON Parsing Function

yamlChangeHandler = (newValue) =>{
  this.setState({yaml: newValue})
 this.converToJson(newValue)
}

converToJson = debounce((yamlString)=>{
  try{
    const newJson = YamlJS.load(yamlString);
    const newJsonAsString = JSON.stringify(newJson || '', null, 2);
    this.setState({json: newJsonAsString});
  }catch(e){
    console.log(e);
  }
}, 1300)

But what will happen if the user was faster that out debounce timeout? Fortunately, Lodash Debounce allows us to execute our function before the timeout ends.

Debounce returns an Object that contains three functions.

  • pending(): return a boolean value to determine if any pending functions are waiting for the timeout ent to invoke.
  • flush(): Execute the function immediately based on the latest passed data/parameters. The return value is the same returned by the original function.
  • cancel(): cancels function invoked and clear all the data passed so far.

All in all, Debounce functions help in delaying invoked functions by waiting for a specific time after the last call for the debounce function to call our logic.