Difference Between Synchronous and Asynchronous Programming (In Node.Js)

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:

  1. Query finished
    Next line
  2. 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,

  1. 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 the Event Loop pushes the tasks available in Callback Queue ( having your callback function that gets called when a action is completed) to the Call Stack and runs it.

  2. Again this depends on Engine on which the program is getting executed. The Node.js uses V8 Engine which has access to Thread pool provided by libuv 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.

  3. 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.

  4. 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:

  1. I've added timestamps to console.log so timing is more obvious
  2. I've added console.log statements immediately before and after the call to f1().

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:

  1. Send request
  2. go on with other code
  3. response come in any time on a callback

Sync:

  1. Send request
  2. Wait for response
  3. 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 baras 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

  1. 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.

  2. 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:

  1. 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").

  2. Yes, callbacks may be invoked from a different thread - but it's certainly not a requirement.

  3. 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

  1. 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.

  2. 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".

  3. 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".

  4. 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).

  5. 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



Leave a reply



Submit