Skip to content

Instantly share code, notes, and snippets.

@dlwjiang
Last active November 5, 2015 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlwjiang/faefb2b1feaf3d2b6787 to your computer and use it in GitHub Desktop.
Save dlwjiang/faefb2b1feaf3d2b6787 to your computer and use it in GitHub Desktop.
ThrottleDebounce

Understanding Throttle and Debounce Through Analogy:

###Throttle:

A lazy person who ignores your commands until he is rested.

###Debounce:

A cranky clerk condescending waiting for you to stop talking before doing anything.

####Note:

For throttle's demonstration, the task animation time is set to the same as the resting time. In most use cases, the task itself is relatively instant so there would be more than 1 dot moving around. Throttle then adjusts the minimum distance between each dot, 'throttling' the firehose of tasks to an acceptable level.

For debounce, the red timer is usually very short. The main purpose is to group multiple actions into 1 action such as accidentally double clicking a save button.

Both actions can be hacked to do the work of the other though it's best to keep the proper model in mind. Throttle 'throttles' the rate of actions while debounce 'throttles' noise so that random noise is not perceived as multiple actions.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.throttle-button, .debounce-button {
cursor: pointer
}
text {
-webkit-user-select: none
}
circle {
fill: #416EE9;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<div id="throttle-area">
<svg></svg>
</div>
<div id="debounce-area">
<svg></svg>
</div>
<script>
var margin = {top: 30, right: 40, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
//var svg = d3.select("body").append("svg")
var throttle = d3.select("#throttle-area svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height/4 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append('g');
throttle.append('rect')
.attr('width', 600)
.attr('height', 100)
.attr('fill', "#eee");
var restPeriod = 3000;
//button
throttle.append('text').text("throttle")
.attr('class', 'throttle-button')
.attr('x', 700)
.attr('y', 50)
.on('click', simpleThrottle(runThrottle,restPeriod));
var throttleCircleGroup = throttle.append('g').attr('class', 'circleGroup')
var throttleText = throttleCircleGroup.append('text')
.attr('y', 20)
.attr('opacity', 0);
var throttleCircle = throttleCircleGroup.append('circle')
.attr('cx', 20)
.attr('cy', 45)
.attr('r', 10);
function runThrottle(){
throttleCircleGroup.transition().duration(restPeriod/2)
.attr('transform', "translate(550,0)")
.transition().duration(restPeriod/2)
.attr('transform', "translate(0,0)")
}
function simpleThrottle(fn, restPeriod){
var free = true;
return function(){
if (free){
fn.apply(this, arguments);
flashText("I'm going!");
free = false;
setTimeout(function(){
free = true;
}, restPeriod)
} else {
flashText("I'm tired T.T");
}
}
}
function flashText(text) {
throttleText.text(text)
.attr('opacity', 1)
.transition().duration(200)
.attr('opacity', 0);
}
var debounce = d3.select("#debounce-area svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height/4 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append('g').attr('class', 'debounce');
debounce.append('rect')
.attr('width', 600)
.attr('height', 100)
.attr('fill', "#eee");
var waitPeriod = 1000;
//button
debounce.append('text').text('debounce')
.attr('class', 'debounce-button')
.attr('x', 700)
.attr('y', 50)
.on('click', simpleDebounce(runDebounce,waitPeriod));
var debounceCircleGroup = debounce.append('g');
debounceCircleGroup.append('circle')
.attr('r', 10)
.attr('cx', 20)
.attr('cy', 45);
var debounceText = debounceCircleGroup
.append('text')
.attr("y", 20)
.text("Are you done yet?")
.attr('opacity', 0);
function runDebounce(){
debounceCircleGroup.transition().duration(100)
.attr('transform', "translate(550,0)")
.transition().duration(100)
.attr('transform', "translate(0,0)")
}
function simpleDebounce(fn, waitPeriod){
var timeout;
return function(){
clearTimeout(timeout);
debounce.append('rect').attr('class', 'timer')
.attr('x', 0)
.attr('y', -5)
.attr('width', 600)
.attr('height', 5)
.attr('fill', "#e00")
.transition().duration(waitPeriod)
.attr('width', 0);
debounceText.attr('opacity', 1)
.transition().duration(100)
.attr('opacity', 0);
timeout = setTimeout(fn,waitPeriod);
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment