Javascript is a single-threaded programming language that can also be non-blocking. This simply means that javascript is a programming language that can be used to carry synchronous and asynchronous tasks.
These two programming styles give javascript a lot of power when it comes to carrying out programming tasks, most especially those that take a long time to complete.
In this article, I will discuss the differences between synchronous and Asynchronous programming, the pros and cons of each of them, and their best use cases.
Differences.
-
Normal functions return a result with the
return
keyword while Async functions return a Promise object (This is an object that contains the state of the promise and the value of the promise).
function sum(a,b) { return a+b; } async function add(a,b) { return a + b; } sum(3,9) add(3,9)
-
Values of Normal function are gotten by calling the function while value of Async function is gotten by using the
await
or.then()
.
function sum(a,b) { return `Normal function : ${3 + 9}`; } async function add(a,b) { return a + b; } sum(3,9) await add(3,9)
Using
.then()
add(3,9).then((value)=> console.log(value))
-
Most functions/methods that naturally run asynchronously require a callback function as a parameter.
new Promise((resolve)=>resolve); setTimeout(()=>,1000); element.addEventListener("click", ()=>)
In synchronous programming, functions that require other functions as parameters are called Higher Order Functions.
function multiplyBy(num) { return function(arg) { return num * arg; } } const multiplyByTwo = mutltiplyBy(2); const multiplyByFour = multiplyBy(4); multiplyByTwo(4) multiplyByFour(4)
-
The javascript engine first runs all synchronous code before running asynchronous code.
console.log("I am the first") //synchronous new Promise((resolve)=>resolve("I am second")).then(console.log); //asynchronous setTimeout(console.log("I am the third"), 2) // asynchronous console.log("Should I be the last") //synchronous setTimeout(console.log("Can I come ?"), 0) // asynchronous
In Javascript all asynchronous codes are first sent to the web API before they are added to the call stack. Asynchronous codes are added to the call stack when all synchronous code(s) have been executed by the javascript engine and have been removed from the call stack.
function printHello() {
console.log('Hello from baz');
}
function baz() {
setTimeout(printHello, 3000);
}
function bar() {
baz();
}
function foo() {
bar();
}
foo();
-
Synchronous programming follows a strict sequence, which means that operations are performed, in perfect order. While one operation is being performed, other operation instructions are blocked.
console.log("Loading file-1 ...") console.log("Loading file-2 ...") console.log("Loading file-3 ...")
With synchronous programming, it would be impossible to load file-2 without loading file-1 .
Asynchronous programming is non-blocking which means it doesn't block further execution while one or more operations are in progress. This also means that multiple operations can run simultaneously without waiting for other tasks to complete.
new Promise((resolve)=>setTimeout(resolve("Loading file-1"),2000)).then(console.log); setTimeout(console.log("Loadinf file-2"),0); btn.addEventListener("click", ()=>console.log("Loading file-3"));
-
Javascript functions that take a very long time before they return can make the user interface(UI) or server unresponsive until the function has returned, resulting in a bad user experience. an example would be to use the alert function to display a message.
The user would not be able to do anything on the web page until a response is given to the alert box.
console.log("Loading file-1 ...") alert("Loading file-2 ...") console.log("Loading file-3 ...")
Asynchronous programming enhances a user's experience by reducing the time it takes for a function to return after it has been called. It does this by running complex functions in the background so that it does not interrupt the user's experience with the application.
For example, it takes time to fetch data from an application programming interface(API) or read a file so rather than stop all other operations we could use asynchronous programming to perform these actions. A bonus here is that the user might think that the application is running very fast.
function load(file) { return new Promise((resolve)=>{ resolve(file) }); }; async function getBigData(bigFile) { const respone = await load(bigFile); console.log(`${bigFile} is ready`); }; function getsmallData(smallFile) { console.log(`${smallFile} is ready`); }; getBigData("File-1"); loadsmallData("File-2"); loadsmallData("File-3"); loadsmallData("File-4");
"File-1" is very large and loading it synchronously can slow down our application. So we load it asynchronously by using a Promise.
Once the javascript engine notices that
getBigData()
is an asynchronous function, it sends it to the web API and continues running other synchronous tasks.Once all synchronous tasks have been completed the event loop checks the micro tasks queue/job queue and runs
getBigData()
on the call stack. -
Asynchronous code is non-blocking, which means that we can send multiple requests to a server at the same time.
const urls = [ 'https://jsonplaceholder.typicode.com/users', 'https://jsonplaceholder.typicode.com/posts', 'https://jsonplaceholder.typicode.com/albums' ]; Promise.all(urls.map((url) => { return fetch(url).then((value) => value.json()); })).then((values) => { console.log(values[0]); console.log(values[1]); console.log(values[2]); }).catch((error) => console.log("Opps there was an error", error));
Synchronous code is blocking which means that it can only send one request and wait for that request to be answered by the server.
With
Promise.all()
we could work on an array of asynchronous operations at once, which is, using thefetch()
to fetch data from a database.
Synchronous programming is advantageous to developers because it is much easier to code. This saves the time it takes for developers to learn something that could open the door to bugs (asynchronous programming).
-
Asynchronous programming should be used in carrying out tasks that do not depend on other tasks for their execution.
<!DOCTYPE html> <html> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <p>Hello</p> <script src="animate.js"></script> <script src="index.js"></script> </html>
Suppose we want to animate the p tags once the page loads using a javascript animation library (animate.js). Since our code, written in
index.js
depends on that, written inanimate.js
it is placed after it.The code in
index.js
is a dependent task because it depends onanimate.js
to successfully carry out its operation, while the libraryanimate.js
is an independent task because it doesn't really on any other code for its execution.The code is read synchronously from the
p
tags to the last script file,index.js
and everything works just as expected. But we could do something interesting here by loadinganimate.js
asynchronously. This means that the script file,animate.js
is parsed same time thep
tags are parsed to increase load time.
<script async src="animate.js"></script>
By adding the
async
keyword, theanimate.js
is loaded at the same time that all thep
tags are loaded. Cool right?By doing this we gain an increment in the load time and our users are happy ☺.
Search engines find it easier to find web pages that make use of synchronous programming. So a business that depends on search engine optimization(SEO) to publicize its reputation and product, synchronous programming would be an advantage an appreciable advantage.
Conclusion
I hope that you have gained something new from this article and you can make wise programming decisions according to what your application requires.
Top comments (4)
This is beautiful ❤️
I love it. A very nice concept and so detailed. I'll be coming back to this article.
Very nice guide, and clear example, thanks.
Great article!!!
Thanks for the suggestion.