Debounce function adalah higher-order function
yang digunakan untuk menunda
eksekusi kode dengan waktu yang ditentukan. Penggunaan fungsi debounce ini
memberikan kontrol agar proses sebelumnya berjalan terlebih dahulu, lalu
mengeksekusi perintah dalam function yang didebounce.
Pada saat mengembangkan aplikasi web dengan menggunakan react atau library/framework javascript lain akan tiba saatnya menghadapi kasus harus menunda pengeksekusian suatu kode agar lebih efisien dan tidak mengganggu performance.
Contoh kasus penggunaan fungsi debounce ini biasanya pada fitur pencarian.
Dengan kode seperti di bawah
import React from "react";
import axios from "axios";
class App extends React.Component {
state = {
data: [],
};
handleChange = async e => {
try {
const animes = await axios.get("https://api.jikan.moe/v3/search/anime", {
params: {
limit: 5,
q: e.target.value,
},
});
this.setState({
data: animes.data.results,
});
} catch (error) {
console.log(error);
}
};
render() {
return (
<>
<h3>Cari anime</h3>
<input
type="text"
onChange={this.handleChange}
placeholder="masukkan judul anime"
style={{ width: "20%" }}
/>
<div>
hasil yang dicari:
<ul>
{this.state.data.map((anime, i) => (
<li key={i}>
{anime.title} ({anime.episodes} eps.){" "}
</li>
))}
</ul>
</div>
</>
);
}
}
export default App;
Setiap kali element input menerima masukkan akan memanggil method handleChange
melalui event handler onChange
. Sedangkan setiap event yang diterima di method
tersebut akan langsung melakukan http request.
Ini berarti akan memberatkan performance karena terlalu banyak request setiap
ada event. Jika kita mau memasukkan keyword naruto
, maka akan ada 6 request.
Setiap huruf yang diketikkan akan langsung dilakukan request dan ini tidak perlu dilakukan, malah akan membebani browser dan menghabiskan internet kuota user.
Oleh karenanya kita hanya ingin melakukan request pada saat user selesai mengetikkan keywordnya. Hal itu bisa kita lakukan dan siasati dengan debounce.
fungsi debounce bisa kita import dari library underscorejs
atau bisa kita buat
file sendiri.
// debounce.js
module.exports = (func, wait, immediate) => {
var timeout;
return function executedFunction() {
var context = this;
var args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Setelah diimport, lalu bungkus method handleChange
dengan debounce
dan beri
waktu tunda untuk menunggu sampai menjalankan method tersebut.
import React from "react";
import axios from "axios";
import debounce from "./debounce";
class App extends React.Component {
state = {
data: [],
};
handleChange = debounce(async keyword => {
try {
const animes = await axios.get("https://api.jikan.moe/v3/search/anime", {
params: {
limit: 5,
q: keyword,
},
});
this.setState({
data: animes.data.results,
});
} catch (error) {
console.log(error);
}
}, 1000);
render() {
return (
<>
<h3>Cari anime</h3>
<input
type="text"
onChange={e => this.handleChange(e.target.value)}
placeholder="masukkan judul anime"
style={{ width: "20%" }}
/>
<div>
hasil yang dicari:
<ul>
{this.state.data.map((anime, i) => (
<li key={i}>
{anime.title} ({anime.episodes} eps.){" "}
</li>
))}
</ul>
</div>
</>
);
}
}
export default App;
Di baris 10-24
kita bungkus perintah method handleChange
menjadi argumen
pertama dari fungsi debounce, argumen kedua kita beri 1000 yang berarti waktu
menunggu 1000ms.
Kemudian di baris 30, di event handler onChange
kita hanya mengirim ke method
handleChange
isi keywordnya dari event element input saat menerima masukan.
Sehingga hasil pada saat menggunakan fungsi debounce
akan seperti ini, hanya
melakukan request satu kali.