Async in JS!
How to express and manipulate program behavior spread out over a period of time?
not about what happens from the beginning of a for loop to the end of a for loop
It's about what happens when part of your program runs now, and another part of your program runs later
- waiting for user input
- requesting data from a database or file system
- sending data across the network and waiting for a response
- etc, etc.
your program is almost certainly comprised of several chunks, only one of which is going to execute now, and the rest of which will execute later
// ajax(..) is some arbitrary Ajax function given by a library
var data = ajax( "http://some.url.1" );
console.log( data );
// what's the output?
The simplest way of "waiting" from now until later is to use a function, commonly called a callback function:
// ajax(..) is some arbitrary Ajax function given by a library
ajax( "http://some.url.1", function myCallbackFunction(data){
console.log( data ); // Yay, I gots me some `data`!
} );
// which code runs now and which later? :P
function now() {
return 21;
}
function later() {
answer = answer * 2;
console.log( "Meaning of life:", answer );
}
var answer = now();
setTimeout( later, 1000 ); // Meaning of life: 42
Gyaan
Any time you wrap a portion of code into a function and specify that it should be executed in response to some event (timer, mouse click, Ajax response, etc.), you are creating a later chunk of your code, and thus introducing asynchrony to your program.
JS is not asynchronous
Yes, JS is an on-demand execution engine and works when asked to!
Hosting Environments
- Browsers
- NodeJS servers
- etc, etc
Explain Ajax Request
// `eventLoop` is an array that acts as a queue (first-in, first-out)
var eventLoop = [ ];
var event;
// keep going "forever"
while (true) {
// perform a "tick"
if (eventLoop.length > 0) {
// get the next event in the queue
event = eventLoop.shift();
// now, execute the next event
try {
event();
}
catch (err) {
reportError(err);
}
}
}
Quiz Master Mathan
Callback Challenge # 1
listen( "click", function handler(evt){
setTimeout( function request(){
ajax( "http://some.url.1", function response(text){
if (text == "hello") {
handler();
}
else if (text == "world") {
request();
}
} );
}, 500) ;
} );
Callback Challenge # 2
doA( function(){
doB();
doC( function(){
doD();
} )
doE();
} );
doF();
// doA()
// doF()
// doB()
// doC()
// doE()
// doD()
Trust Issues :P
// A
ajax( "..", function(..){
// C
// now you've just handed over your piece of code
// to a third party!
// are you absolutely sure this third-party
// lib ajax will call your callback?
} );
// B
Trust Issues :P Contd.
// exaggerated scenario
analytics.trackPurchase( purchaseData, function(){
chargeCreditCard();
displayThankyouPage();
} );
Trust Issues :P Contd.
// exaggerated scenario
var tracked = false;
analytics.trackPurchase( purchaseData, function(){
if (!tracked) {
tracked = true;
chargeCreditCard();
displayThankyouPage();
}
} );
Problems that can occur
- Call the callback too early (before it's been tracked)
- Call the callback too late (or never)
- Call the callback too few or too many times (like the problem you encountered!)
- Fail to pass along any necessary environment/parameters to your callback
- Swallow any errors/exceptions that may happen
- ...
And you thought the only problem with callbacks was sideways nesting, Ha!
Async in JS!
By Ankeet Maini
Async in JS!
- 168