This website uses cookies and similar technologies to understand visitors' experiences. By continuing to use this website, you accept our use of cookies and similar technologies,Terms of Use, and Privacy Policy.

Jun 03 2015 - 03:04 PM
Javascript's Amazing Closures
While working on mSchool today, we ran into this feature where we wanted to show some kind of a notification on the page for a fleeting amount of time to signal to the user that their stuff was being saved. Think of it, like Gmail, which shows the "saved" thing, every once in a while to let you know your draft is being saved. How would you implement it? On the surface, it looks pretty straight-forward but when you get to actually coding it out, you realize it's not. Here's how the rough algorithm would look: - Wait for the user to start typing something - Wait for them to stop - If some amount of time has elapsed (say half a second) show the "saved" message and actually save it. The tricky part is, how would you know someone has "stopped" typing. Javascript has a "keyup" event that you can hook into, whenever a key is released and you could hook into that. But... that is not the same as what we think of someone "stopping" typing. For example, if I type the words "hey there" -- I have fired about 9 keyups (one for each letter). Here's one solution around this.
  1. Take a timestamp whenever someone does a "keyup".
  2. Create a deferred function, i.e. a function that will run after sometime (say 2 seconds). This function will do the actual saving.
  3. Whenever the deferred function runs, check to see if the timestamp from Step 1 is less than what you would think of as "not stopping" (say 1 second). That is, it's common sense to assume that if someone takes less than one second between the typing of two characters, they haven't actually stopped typing.
Most languages, would have a really hard time capturing this, but Javascript does a pretty good job of wrangling this out. Anways, less talk, more code.. function stoppedTyping() { deferredFunction = setTimeout(function() { var firedTooSoon = (Date.now() - Session.get('lastSaveTime')) > 1 * 1000; if(firedTooSoon) { console.error(arTimeout(deferredFunction); } else { alert("hey there"); } }, 1000); } $("#field-input").keyup(stoppedTyping); The fact that this just works, is awesome! That *deferredFunction* is actually in scope inside the anonymous function in setTimeout, is really really amazing and a testament to what Javascript got absolutely right, stealing closures from Scheme.
Posted in: Education|By: Santosh Kumar|823 Reads