Last active
March 3, 2016 21:35
-
-
Save samhavens/4943ff1018b674d64e11 to your computer and use it in GitHub Desktop.
Intro to Asynchronicity in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
***Here is my attempt at explaining the default params in a standard callback in JavaScript*** | |
When you see something like the following... | |
*/ | |
storage.users.get(message.user, function(err, user) { | |
if (user && user.name) { | |
reply(Hello + ' ' + user.name + '!') | |
} else { | |
reply(Hello + '.') | |
} | |
}) | |
/* | |
Where do err and user (in the function in the second slot of get()) come from? | |
Well, let's look at what it "should" look like, for those of us not used to asynchronicity | |
(The following code pretends that | |
things happen synchronously in JS, like they would in PHP) | |
*/ | |
function getThingsFromSomeAPI(params) { | |
//hit API, get either an error or information | |
return [error, response] | |
} | |
var err, res | |
try { | |
[err, res] = getThingsFromSomeAPI( { key1:value1, key2:value2 } ) | |
} catch { | |
err | |
} | |
doStuffWithResponse(res) | |
/* | |
Hah! Wouldn't that be nice. | |
Javascript doesn't wait for functions to finish however, and the default way of handling this is callbacks | |
Here is what actually happens | |
*/ | |
function getThingsFromSomeAPI(params, callback) { | |
//still hit the same api and define the same error and response variables | |
//but now we have to tell the function that gets called what the variables are ONCE THEY EXIST | |
//the first parameter is irrelevant for this explanation, but fyi it changes the context, eg the value of `this`\ | |
//the second is an array of arguments that are passed as arguments to the callback | |
callback.apply(null, [error, response]) | |
} | |
//this is how the code would actually be written in javascript | |
getThingsFromSomeAPI( { key1:value1, key2:value2 }, function(err, res) { | |
if err throw err | |
else doStuffWithResponse(res) | |
}) | |
//here is one change that makes it more readable | |
getThingsFromSomeAPI( { key1:value1, key2:value2 }, function handleAPIResponse(err, res) { | |
if err throw err | |
else doStuffWithResponse(res) | |
}) | |
/* | |
so the function handleAPIResponse gets called, and | |
it gets passed the array [error, response] which sets | |
err = error, and res = response | |
So, going back to the original example: | |
*/ | |
storage.users.get(message.user, function(err, user) { | |
if (user && user.name) { | |
reply(Hello + ' ' + user.name + '!') | |
} else { | |
reply(Hello + '.') | |
} | |
}) | |
/* | |
If things were synchronous, the function storage.users.get would be called like | |
[err, user] = storage.users.get(message.user) | |
But in JS that means | |
"set err and user equal to the undefined value that storage.users.get(message.user) has at this moment" | |
Really, what we want to do is | |
"Look up this user, THEN set any errors you encounter to err, and the result to res" | |
so we pass the function, and say, | |
"Hey, once you're done with the lookup, call this function, and set the values of its two parameters to the values you would have returned" | |
I hope this made sense. If you want to ask questions, HMU @sam_havens on twitter | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment