Understanding Asynchronous Code in Layman's terms
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!
Easy to understand definition of asynchronous event?
Non programming example:
Synchronous
You want a pizza for dinner and you are out of the frozen kind. So you have to stop playing WOW which upsets your guild. You go to the kitchen, make the dough, cover it with sauce, add the cheese, and smother it your favorite bacon topping. You just spent 20 minutes of your time making the pizza with another 10 minutes in the oven. The timer beeps and you pull the hot pie out. You can sit back down in front of your computer, eat the pizza, and continue with your raid.
Asynchronous
You want a pizza for dinner while playing WOW. You open up a browser window on your 5th monitor. You load up the Pizza website and order your extra cheesy bacon pizza with a side of bacon grease garlic sauce. You go back to your raid and after 20 minutes the door bell rings. You get the pizza. You sit back down in front of your computer, eat the pizza, and continue with your raid.
So what is the difference? One way you waste 20-30 minutes of precious WOW time, the other way you waste $20 plus tip.
Asynchronous Vs Synchronous Code In JavaScript
Long answer short, JavaScript is not completely single threaded. While execution, internal threads are created to handle Async functionality like xmlhttprequest
.
Now coming to your doubts,
Yes if the request is Async like an I/O operation, depending on the JavaScript Engine it creates separate thread for it and executes in background while the main process still runs, once the
Call Stack
is empty theEvent Loop
pushes the tasks available inCallback Queue
( having your callback function that gets called when a action is completed) to the Call Stack and runs it.Again this depends on Engine on which the program is getting executed. The Node.js uses
V8 Engine
which has access toThread pool
provided bylibuv
which creates limited no. of threads and assign tasks to each one of them. For example 10 requests to download a file may be handled by first creating 4 threads to download file for first 4 requests, after downloaded again download other 4, then finally the rest 2 files get downloaded. Callback functions get called in the same order.setInterval
,setTimeout
,xmlhttprequest
are functionalities which are provided additionally and is not part of native JavaScript. So whenever such function is called, external packages work on it while still the main JavaScript program continues to run, when the Async function gets finished it simply calls the Callback function with the result data. As you are familiar with Event Loop, it is the one which handles calling the Callback function from Callback Queue.As I said each browser has different JavaScript Engine and has different ways to handle things. NodeJS uses Google's V8 Engine and has a package called
libuv
which handles Async stuff. I would suggest you to refer below link:
Overview of Blocking vs Non-Blocking in NodeJS
Asynchronous vs synchronous execution. What is the difference?
When you execute something synchronously, you wait for it to finish before moving on to another task. When you execute something asynchronously, you can move on to another task before it finishes.
In the context of operating systems, this corresponds to executing a process or task on a "thread." A thread is a series of commands (a block of code) that exist as a unit of work. The operating system runs a given thread on a processor core. However, a processor core can only execute a single thread at once. It has no concept of running multiple threads simultaneously. The operating system can provide the illusion of running multiple threads at once by running each thread for a small slice of time (such as 1ms), and continuously switching between threads.
Now, if you introduce multiple processor cores into the mix, then threads CAN execute at the same time. The operating system can allocate time to one thread on the first processor core, then allocate the same block of time to another thread on a different processor core. All of this is about allowing the operating system to manage the completion of your task while you can go on in your code and do other things.
Asynchronous programming is a complicated topic because of the semantics of how things tie together when you can do them at the same time. There are numerous articles and books on the subject; have a look!
Simple question about asynchronous programming
Despite being imprecise about the thread being blocked (which is incorrect as pointed out in the comments),
you are correct.
While 'more performing' may mean many things, assuming that both operations are independent, Task.WhenAll
option will finish earlier.
Having
var work1 = async () => await Task.Delay(1000);
var work2 = async () => await Task.Delay(2000);
await work1();
await work2();
will take 3 seconds,
and
await Task.WhenAll(work1(), work2());
will take 2 seconds.
Understanding F# Asynchronous Programming
The "async" in this example is not about concurrency or saving time, rather it's about providing a good programming model without blocking (read: wasting) threads.
If using other programming languages, typically you have two choices:
You can block, typically by calling synchronous methods. The disadvantage is that the thread is consumed and doing no useful work while it waits for the disk or network I/O or what have you. The advantage is it the code simple (normal code).
You can use callbacks to call asynchronously and get notifications when operations complete. The advantage is you don't block threads (these threads can be returned e.g. to the ThreadPool and a new ThreadPool thread will be used when the operation completes to call you back). The disadvantage is that a simple block of code gets divided up into a bunch of callback methods or lambdas, and it quickly becomes very complicated to maintain state/control-flow/exception-handling across the callbacks.
So you're between a rock and a hard place; you either give up the simple programming model or you waste threads.
The F# model gives the best of both worlds; you don't block threads, but you keep the straightforward programming model. Constructs like let!
enable you to 'thread-hop' in the middle of an async block, so in code like
Blah1()
let! x = AsyncOp()
Blah2()
Blah1
may run on, say, ThreadPool thread #13, but then AsyncOp will release that thread back to the ThreadPool. Later when the AsyncOp completes, the rest of the code will start back up on an available thread (maybe, say, ThreadPool thread #20) which binds x
to the result and then runs Blah2
. In trivial client apps this rarely matters (except when ensuring you don't block the UI thread), but in server apps that do I/O (where threads are often a precious resource - threads are expensive and you can't waste them by blocking) non-blocking I/O is often the only way to make an application scale. F# enables you to write non-blocking I/O without having the program degrade into a mass of spaghetti-code callbacks.
See also
Best practices to parallelize using async workflow
How to do chained callbacks in F#?
http://cs.hubfs.net/forums/thread/8262.aspx
How and when to use ‘async’ and ‘await’
When using async
and await
the compiler generates a state machine in the background.
Here's an example on which I hope I can explain some of the high-level details that are going on:
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
OK, so what happens here:
Task<int> longRunningTask = LongRunningOperationAsync();
starts executingLongRunningOperation
Independent work is done on let's assume the Main Thread (Thread ID = 1) then
await longRunningTask
is reached.Now, if the
longRunningTask
hasn't finished and it is still running,MyMethodAsync()
will return to its calling method, thus the main thread doesn't get blocked. When thelongRunningTask
is done then a thread from the ThreadPool (can be any thread) will return toMyMethodAsync()
in its previous context and continue execution (in this case printing the result to the console).
A second case would be that the longRunningTask
has already finished its execution and the result is available. When reaching the await longRunningTask
we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000)
involved.
Understanding async/await on NodeJS
To clear a few doubts -
- You can use
await
with any function which returns a promise. The function you're awaiting doesn't need to beasync
necessarily. - You should use
async
functions when you want to use theawait
keyword inside that function. If you're not gonna be using theawait
keyword inside a function then you don't need to make that functionasync
. async
functions by default return a promise. That is the reason that you're able toawait
async
functions.
From MDN -
When an async function is called, it returns a Promise.
As far as your code is concerned, it could be written like this -
const getUsers = (ms) => { // No need to make this async
return new Promise(resolve => setTimeout(resolve, ms));
};
// this function is async as we need to use await inside it
export const index = async (req, res) => {
await getUsers(5000);
res.json([
{
id: 1,
name: 'John Doe',
},
{ id: 2,
name: 'Jane Doe',
},
]);
};
Related Topics
How to Obtain the Query String from the Current Url with JavaScript
Angular 4 Interceptor Retry Requests After Token Refresh
Open File Dialog Box in JavaScript
Shiny Slider Input Step by Month
How to Programmatically Click on an Element in JavaScript
How to Write an Inline If Statement in JavaScript
How to Extract Text from a PDF in JavaScript
How to Render a Partial from JavaScript
Understanding Promises in Node.Js
How to Pass an Object into a State Using Ui-Router
Angular Cli Webpack, How to Add or Bundle External Js Files
Differencebetween Regexp's Exec() Function and String's Match() Function
How to Access the Http Request Header Fields via JavaScript
Jquery Scrolltop() Doesn't Seem to Work in Safari or Chrome (Windows)
The Best Way to Synchronize Client-Side JavaScript Clock with Server Date