I understand the basic thing about asynchronous-ness: things don't execute sequentially. And I understand there is something very powerful about that... allegedly. But for the life of me I can't wrap my head around the code. Let's take a look at async Node.JS code that I HAVE WRITTEN...but don't truly get.
function newuser(response, postData) { console.log("Request handler 'newuser' was called."); var body = '<html>' + '<head>' + '<meta http-equiv="Content-Type" content="text/html; ' + 'charset=UTF-8" />' + '</head>' + '<body>' + '<form action=" /thanks" method="post">' + '<h1> First Name </h1>' + '<textarea name="text" rows="1" cols="20"></textarea>' + '<h1> Last Name </h1>' + '<textarea name="text" rows="1" cols="20"></textarea>' + '<h1> Email </h1>' + '<textarea name="text" rows="1" cols="20"></textarea>' + '<input type="submit" value="Submit text" />' + '</body>' + '</html>'; response.writeHead(200, { "Content-Type": "text/html" }); response.write(body); response.end(); }
Where did response come from again? postData? Why can't I define a variable in this "callback" and then use it outside of the callback? Is there a way to have a few things be sequential then the rest of the program async?
Also known as nonblocking code, asynchronous programming provides opportunities for a program to continue running other code while waiting for a long-running task to complete. The time-consuming task is executed in the background while the rest of the code continues to execute.
Asynchronous programming is a technique that enables your program to start a potentially long-running task and still be able to be responsive to other events while that task runs, rather than having to wait until that task has finished.
An asynchronous model allows multiple things to happen at the same time. When you start an action, your program continues to run. When the action finishes, the program is informed and gets access to the result (for example, the data read from disk).
To check if a function is async, access the constructor.name property on the function and check if the value is equal to AsyncFunction , e.g. myFunction.constructor.name === 'AsyncFunction' . If the equality check returns true , then the function is async.
I'm not sure where this function is being used, but the point of callbacks is that you pass them into some function that runs asynchronously; it stores your callback away, and when that function is done with whatever it needs to do, it will call your callback with the necessary parameters. An example from front-to-back is probably best.
Imagine we have a framework, and in it there is an operation that runs for a long time, fetching some data from the database.
function getStuffFromDatabase() { // this takes a long time };
Since we don't want it to run synchronously, we'll allow the user to pass in a callback.
function getStuffFromDatabase(callback) { // this takes a long time };
We'll simulate taking a long time with a call to setTimeout
; we'll also pretend we got some data from the database, but we'll just hardcode a string value.
function getStuffFromDatabase(callback) { setTimeout(function() { var results = "database data"; }, 5000); };
Finally, once we have the data, we'll call the callback given to us by the user of the framework's function.
function getStuffFromDatabase(callback) { setTimeout(function() { var results = "database data"; callback(results); }, 5000); };
As a user of the framework, you'd do something like this to use the function:
getStuffFromDatabase(function(data) { console.log("The database data is " + data); });
So, as you can see data
(same as response
and postData
in your example) came from the function that you pass your callback into; it gives that data to you when it knows what that data should be.
The reason you can't set a value in your callback and use it outside the callback is because the callback itself doesn't happen until later in time.
// executed immediately executed sometime in the future // | | by getStuffFromDatabase // v v getStuffFromDatabase(function(data) { var results = data; // <- this isn't available until sometime in the future! }); console.log(results); // <- executed immediately
When the console.log
runs, the assignment of var results
hasn't happened yet!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With