What is the difference between synchronous and asynchronous programming (in node.js)
The difference is that in the first example, the program will block in the first line. The next line (console.log
) will have to wait.
In the second example, the console.log
will be executed WHILE the query is being processed. That is, the query will be processed in the background, while your program is doing other things, and once the query data is ready, you will do whatever you want with it.
So, in a nutshell: The first example will block, while the second won't.
The output of the following two examples:
// Example 1 - Synchronous (blocks)
var result = database.query("SELECT * FROM hugetable");
console.log("Query finished");
console.log("Next line");
// Example 2 - Asynchronous (doesn't block)
database.query("SELECT * FROM hugetable", function(result) {
console.log("Query finished");
});
console.log("Next line");
Would be:
Query finished
Next line
Next line
Query finished
Note
While Node itself is single threaded, there are some task that can run in parallel. For example, File System operations occur in a different process.
That's why Node can do async operations: one thread is doing file system operations, while the main Node thread keeps executing your javascript code. In an event-driven server like Node, the file system thread notifies the main Node thread of certain events such as completion, failure, or progress, along with any data associated with that event (such as the result of a database query or an error message) and the main Node thread decides what to do with that data.
You can read more about this here: How the single threaded non blocking IO model works in Node.js
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
Difference between synchronous and asynchronous functions
This is a challenging topic when coming from other programming languages. Using your terminology, a 'normal' function is akin to a synchronous function.
I'd recommend the MDN docs for await. Read that page and then run the f1
example -- I've included it below with a couple of enhancements:
- I've added timestamps to console.log so timing is more obvious
- I've added
console.log
statements immediately before and after the call tof1()
.
The await
keyword doesn't mean wait (or block) when inside an async function. It splits the execution flow, pausing the f1
function (which will be resumed about 2 seconds later) and returning a Promise to the caller that allows the caller of the async function to choose if he wants to await the result of the async function or not. In the code below we print out the result of the call to f1()
but we choose not to await the deferred result and we just continue onwards to the next console.log
.
Run this code in Node.js:
///////////////////////////////////////////////////////////////////////
// This is just setting up timestamps for console.log
///////////////////////////////////////////////////////////////////////
const oldlog = console.log;
console.log = function () {
var args = [].slice.call(arguments);
oldlog.apply(console.log,[getTimestamp()].concat(args));
};
const getTimestamp = () => '[' + (new Date()).toISOString() + ']';
///////////////////////////////////////////////////////////////////////
// Real code starts here
///////////////////////////////////////////////////////////////////////
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
console.log('enter f1');
const x = await resolveAfter2Seconds(10);
console.log('exit f1, x =', x);
return x;
}
console.log('before f1');
const y = f1();
console.log('after f1, y =', y);
When run, this will result in something like the following:
[2020-03-03T01:48:50.716Z] before f1
[2020-03-03T01:48:50.719Z] enter f1
[2020-03-03T01:48:50.720Z] after f1, y = Promise { <pending> }
[2020-03-03T01:48:52.725Z] exit f1, x = 10
Note specifically that we see the after f1
log before we see the exit f1
log. The execution flow was split and f1()
was paused while the caller of f1()
continued. The execution of f1()
resumed about 2 seconds later.
Now, compare that with what happens if we instead await
the result from calling f1()
. Note that because we are now using await
we must wrap the code in async
(an async IIFE, actually) because await
can only be used inside an async
function.
// console.log('before f1');
// const y = f1();
// console.log('after f1, y =', y);
(async () => {
console.log('before f1');
const y = await f1();
console.log('after f1, y =', y);
})();
Now, the output is as follows:
[2020-03-03T02:19:18.122Z] before f1
[2020-03-03T02:19:18.124Z] enter f1
[2020-03-03T02:19:20.130Z] exit f1, x = 10
[2020-03-03T02:19:20.130Z] after f1, y = 10
Note that now, because the caller chose to await the result of calling f1()
, we see the after f1
and exit f1
logs reversed (and in the 'normal' order, using your terminology). And now the result of f1()
is 10, rather than a pending Promise.
So, this is mildly tricky stuff and I encourage more reading and experimentation to get to grips with it. It looks complex but it is actually simpler to write asynchronous JavaScript code now than it was prior to the introduction of async/await into the language.
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!
Asynchronous Vs synchronous in NodeJS
Async:
- Send request
- go on with other code
- response come in any time on a callback
Sync:
- Send request
- Wait for response
- go on with other code after response
Promise is synchronous or asynchronous in node js
The function you pass into the Promise constructor runs synchronously, but anything that depends on its resolution will be called asynchronously. Even if the promise resolves immediately, any handlers will execute asynchronously (similar to when you setTimeout(fn, 0)
) - the main thread runs to the end first.
This is true no matter your Javascript environment - no matter whether you're in Node or a browser.
console.log('start');
const myProm = new Promise(function(resolve, reject) {
console.log('running');
resolve();
});
myProm.then(() => console.log('resolved'));
console.log('end of main block');
Synchronous vs Asynchronous Nodejs
Below is a simplified version of my server code. I demonstrate both synchronous code (after you start doing an operation, no further operations are begun until it finishes) and asynchronous code (you start doing an operation, then continue to do other operations, and at some later point you "callback" or get a result from the first operation.)
This has some important consequences. Nearly every time you call an async function:
the return value from your async function is useless, because the function will return immediately, although finding the result takes a long time.
you have to wait until the callback function is executed to have access to the result.
lines of code following the call to the asynchronous function will execute BEFORE the asynchronous callback function runs.
As an example, the order of the console.logs in my code below will be:
line 3 - before sync
line 8 - after sync, before async
line 16 - after async call, outside callback
line 14 - inside async call and callback
// synchronous operations execute immediately, subsequent code
// doesn't execute until the synchronous operation completes.
console.log('line 3 - before sync');
var app = require('express')();
var cfgFile = require('fs').readFileSync('./config.json');
var cfg = JSON.parse(cfgFile);
var server = require('http').createServer(app);
console.log('line 8 - after sync, before async');
// When you call an asynchronous function, something starts happening,
// and the callback function will be run later:
server.listen(cfg.port, function(){
// Do things that need the http server to be started
console.log('line 14 - inside async call and callback');
});
console.log('line 16 - after async call, outside callback');
Synchronous vs Asynchronous code with Node.js
Let's say you have two functions, foo
and bar
, which are executing synchronously:
function foo() {
var returnValue = bar();
console.log(returnValue);
}
function bar() {
return "bar";
}
In order to make the API "asynchronous" is to change it to use callbacks:
function foo() {
bar(function(returnValue) {
console.log(returnValue);
});
}
function bar(callback) {
callback("bar");
}
But the fact of the matter is, this code is still entirely synchronous. The callback is being executed on the same call stack, and no threading optimizations are being made, no scalability benefits are to be had.
It then becomes a question of code readablity and coding style. I personally find the typical var val = func();
type code more readable and readily understandable. The only drawback is, that if you one day would need to change the functionality of bar
so, that it would need to perform some I/O activity or call some other function which is asynchronous, you need to change the API of bar
as well.
My personal preference: use traditional, synchnous patterns when applicable. Always use asynchronous style when I/O is involved or when in doubt.
What is the difference between Asynchronous calls and Callbacks
Very simply, a callback needn't be asynchronous.
http://docs.apigee.com/api-baas/asynchronous-vs-synchronous-calls
Synchronous:
If an API call is synchronous, it means that code execution will
block (or wait) for the API call to return before continuing. This
means that until a response is returned by the API, your application
will not execute any further, which could be perceived by the user as
latency or performance lag in your app. Making an API call
synchronously can be beneficial, however, if there if code in your app
that will only execute properly once the API response is received.Asynchronous:
Asynchronous calls do not block (or wait) for the API call to return
from the server. Execution continues on in your program, and when the
call returns from the server, a "callback" function is executed.
In Java, C and C#, "callbacks" are usually synchronous (with respect to a "main event loop").
In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked.
If you don't care what Javascript events occur in which order - great. Otherwise, one very powerful mechanism for managing asynchronous behavior in Javascript is to use "promises":
http://www.html5rocks.com/en/tutorials/es6/promises/
PS:
To answer your additional questions:
Yes, a callback may be a lambda - but it's not a requirement.
In Javascript, just about every callback will be an "anonymous function" (basically a "lambda expression").
Yes, callbacks may be invoked from a different thread - but it's certainly not a requirement.
Callbacks may also (and often do) spawn a thread (thus making themselves "asynchronous").
'Hope that helps
====================================================================
Hi, Again:
Q: @paulsm4 can you please elaborate with an example how the callback
and asynchronous call works in the execution flow? That will be
greatly helpful
First we need to agree on a definition for "callback". Here's a good one:
https://en.wikipedia.org/wiki/Callback_%28computer_programming%29
In computer programming, a callback is a piece of executable code that
is passed as an argument to other code, which is expected to call back
(execute) the argument at some convenient time. The invocation may be
immediate as in a synchronous callback, or it might happen at a later
time as in an asynchronous callback.We must also define "synchronous" and "asynchronous". Basically - if a callback does all it's work before returning to the caller, it's "synchronous". If it can return to the caller immediately after it's invoked - and the caller and the callback can work in parallel - then it's "asynchronous".
The problem with synchronous callbacks is they can appear to "hang". The problem with asynchronous callbacks is you can lose control of "ordering" - you can't necessarily guarantee that "A" will occur before "B".
Common examples of callbacks include:
a) a button press handler (each different "button" will have a different "response"). These are usually invoked "asynchronousy" (by the GUI's main event loop).
b) a sort "compare" function (so a common "sort()" function can handle different data types). These are usually invoked "synchronously" (called directly by your program).
A CONCRETE EXAMPLE:
a) I have a "C" language program with a "print()" function.
b) "print()" is designed to use one of three callbacks: "PrintHP()", "PrintCanon()" and "PrintPDF()".
c) "PrintPDF()" calls a library to render my data in PDF. It's synchronous - the program doesn't return back from "print()" until the .pdf rendering is complete. It usually goes pretty quickly, so there's no problem.
d) I've coded "PrintHP()" and "PrintCanon()" to spawn threads to do the I/O to the physical printer. "Print()" exits as soon as the thread is created; the actual "printing" goes on in parallel with program execution. These two callbacks are "asynchronous".
Q: Make sense? Does that help?
Related Topics
Sum JavaScript Object Propertya Values With the Same Object Propertyb in an Array of Objects
Arrow Function Without Curly Braces
How to Find Object in Array by Property in JavaScript
How to Hover in Reactjs? - Onmouseleave Not Registered During Fast Hover Over
How to Make Jquery to Not Round Value Returned by .Width()
What Is the Best Method to Reduce the Size of My JavaScript and CSS Files
Angularjs CSS Animation + Done Callback
Rails 4: Disable Turbolinks in a Specific Page
Handle Response - Syntaxerror: Unexpected End of Input When Using Mode: 'No-Cors'
Backslashes - Regular Expression - JavaScript
How to Highlight Text Using JavaScript
Why Is Null an Object and What's the Difference Between Null and Undefined
Force Browser to Refresh CSS, JavaScript, etc
How to Dynamically Modify <Select> in Materialize CSS Framework
Get the Size of a CSS Background Image Using JavaScript