We, the people, like structure. We like categories and descriptions and putting everything we know into tidy little boxes. This is why I found JavaScript so confusing at first. Is it a scripting or a programming language? Is it used on the front or back end? The wonderful (read: awful) thing about JavaScript is that, most of the time, it’s a little bit of both. JavaScript has evolved so much over the years that it’s slippery
to categorize. Today, I’m just going to dive into whether JavaScript is synchronous or asynchronous, and what workflow looks like under the hood. Spoiler: at its base, JavaScript is a synchronous, blocking, single-threaded language. That just means that only one operation can be in progress at a time. That’s not the entire story, though! What if you have to make an expensive database request? You don’t want to be twiddling your thumbs while ol’ PG and Postgres grab those 800 songs you need for your music library. Synchronous code makes a programmer’s life very difficult, so the JavaScript community developed some great workarounds. When you hear folks say that JavaScript is an
asynchronous language, what they mean is that you can manipulate JavaScript to behave in an asynchronous way. It’s not baked in, but it’s possible! Here are a few ways to make that happen: The earliest and most straightforward solution to being stuck in the synchronous world was asynchronous callbacks (think Let’s use a database request as an example: asynchronous callbacks allow you to invoke
a callback function which sends a database request (and any other nested callbacks) off to your app, where it waits for the response from the database, freeing up the rest of your code to continue running. Once the database request completes, the results (and any other nested code) are sent to the queue,
and then processed through the event loop. In the diagram here, you can see how this differs from synchronous code. Function C, along with E, F and G are all sent off to the browser, queue and event loop. If you want a wonderful, clear explanation of this process, check out this demonstration by Philip Roberts. Now, this is
a great solution, but it leaves a little something to be desired. Because you can’t predict exactly when function C will resolve, you have to nest all dependent functions within it. This gets messy fast, and leads to the infamous callback hell that no one wants to deal with. It was this environment that inspired the promise: In order to deal with callback hell, libraries like Bluebird or Q allowed programmers to clean up their syntax and
write code that operated asynchronously but looked synchronous. This resulted in code that was easier to read and faster to run. With a promise, instead of bundling all dependencies into one code block and sending the entire
thing off to the browser, we’re able to separate them out. We can send the asynchronous callback (Function C) to the browser, and use This allows us to code in a more modular, readable way, while still gaining the benefits of asynchronous programming. Async/AwaitPromises were fantastic — so fantastic, in fact, that ES6 brought them into the language as a standard. Using promises still left asynchronous code looking and feeling slightly wonky, so we now have beautiful and stunning Async/Await to help us out! The Example For Async Await:- There are entire blog posts and (I’m sure) books written about Async/Await, so I’m not going to go into it in too much depth, but suffice it to say that Async/Await allows you to:
for more on javascript and React Js follow: https://medium.com/@ankitkamboj18 Learn How JavaScript WorksPhoto by Sean Lim on UnsplashJavaScript is a single-threaded programming language which means only one thing can happen at a time. That is, the JavaScript engine can only process one statement at a time in a single thread. While the single-threaded languages simplify writing code because you don’t have to worry about the concurrency issues, this also means you can’t perform long operations such as network access without blocking the main thread. Imagine requesting some data from an API. Depending upon the situation the server might take some time to process the request while blocking the main thread making the web page unresponsive. That’s where asynchronous JavaScript comes into play. Using asynchronous JavaScript (such as callbacks, promises, and async/await), you can perform long network requests without blocking the main thread. While it’s not necessary that you learn all these concepts to be an awesome JavaScript developer, it’s helpful to know :) So without further ado, Let’s get started :) Tip: Using Bit you can turn any JS code into an API you can share, use and sync across projects and apps to build faster and reuse more code. Give it a try. How Does Synchronous JavaScript Work?Before we dive into asynchronous JavaScript, let’s first understand how the synchronous JavaScript code executes inside the JavaScript engine. For example: const second = () => { To understand how the above code executes inside the JavaScript engine, we have to understand the concept of the execution context and the call stack (also known as execution stack). Execution ContextAn Execution Context is an abstract concept of an environment where the JavaScript code is evaluated and executed. Whenever any code is run in JavaScript, it’s run inside an execution context. The function code executes inside the function execution context, and the global code executes inside the global execution context. Each function has its own execution context. Call StackThe call stack as its name implies is a stack with a LIFO (Last in, First out) structure, which is used to store all the execution context created during the code execution. JavaScript has a single call stack because it’s a single-threaded programming language. The call stack has a LIFO structure which means that the items can be added or removed from the top of the stack only. Let’s get back to the above code snippet and try to understand how the code executes inside the JavaScript engine. const second = () => {Call Stack for the above code So What’s Happening Here?When this code is executed, a global execution context is created (represented by Next,
The program completes its execution at this point, so the global execution context( How Does Asynchronous JavaScript Work?Now that we have a basic idea about the call stack, and how the synchronous JavaScript works, let’s get back to the asynchronous JavaScript. What is Blocking?Let’s suppose we are doing an image processing or a network request in a synchronous way. For example: const processImage = (image) => { Doing image processing and network request takes time. So when When the At last when the So you see, we have to wait until the function (such as So what’s the solution?The simplest solution is asynchronous callbacks. We use asynchronous callbacks to make our code non-blocking. For example: const networkRequest = () => { Here I have used To understand how this code is executed we have to understand a few more concepts such event loop and the callback queue (also known as task queue or the message queue). An Overview of JavaScript Runtime EnvironmentThe event loop, the web APIs and the message queue/task queue are not part of the JavaScript engine, it’s a part of browser’s JavaScript runtime environment or Nodejs JavaScript runtime environment (in case of Nodejs). In Nodejs, the web APIs are replaced by the C/C++ APIs. Now let’s get back to the above code and see how it’s executed in an asynchronous way. const networkRequest = () => {Event Loop When the above code loads in the browser, the Next The Meanwhile, the timer has expired, now the callback is pushed to the message queue. But the callback is not immediately executed, and that’s where the event loop kicks in. The Event LoopThe job of the Event loop is to look into the call stack and determine if the call stack is empty or not. If the call stack is empty, it looks into the message queue to see if there’s any pending callback waiting to be executed. In this case, the message queue contains one callback, and the call stack is empty at this point. So the Event loop pushes the callback to the top of the stack. After that the DOM EventsThe Message queue also contains the callbacks from the DOM events such as click events and keyboard events. For example: document.querySelector('.btn').addEventListener('click',(event) => { In case of DOM events, the event listener sits in the web APIs environment waiting for a certain event (click event in this case) to happen, and when that event happens, then the callback function is placed in the message queue waiting to be executed. Again the event loop checks if the call stack is empty and pushes the event callback to the stack if it’s empty and the callback is executed. We have learned how the asynchronous callbacks and DOM events are executed which uses the message queue to store all the callbacks waiting to be executed. ES6 Job Queue/ Micro-Task queueES6 introduced the concept of job queue/micro-task queue which is used by Promises in JavaScript. The difference between the message queue and the job queue is that the job queue has a higher priority than the message queue, which means that promise jobs inside the job queue/ micro-task queue will be executed before the callbacks inside the message queue. For example: console.log('Script start');setTimeout(() => { Output: Script start We can see that the promise is executed before the Let’s take another example, this time with two promises and two setTimeout. For example: console.log('Script start');setTimeout(() => { This prints: Script start We can see that the two promises are executed before the callbacks in the While the event loop is executing the tasks in the micro-task queue and in that time if another promise is resolved, it will be added to the end of the same micro-task queue, and it will be executed before the callbacks inside the message queue no matter for how much time the callback is waiting to be executed. For example: console.log('Script start');setTimeout(() => { This prints: Script start So all the tasks in micro-task queue will be executed before the tasks in message queue. That is, the event loop will first empty the micro-task queue before executing any callback in the message queue. ConclusionSo we have learned how asynchronous JavaScript works and other concepts such as call stack, event loop, message queue/task queue and job queue/micro-task queue which together make the JavaScript runtime environment. While it’s not necessary that you learn all these concepts to be an awesome JavaScript developer, but it’s helpful to know these concepts :) That’s it and if you found this article helpful, please click the clap 👏button, you can also follow me on Medium and Twitter, and if you have any doubt, feel free to comment! I’d be happy to help :) Learn moreWhy is JavaScript asynchronous?JavaScript is only asynchronous in the sense that it can make, for example, Ajax calls. The Ajax call will stop executing and other code will be able to execute until the call returns (successfully or otherwise), at which point the callback will run synchronously. No other code will be running at this point.
Why JavaScript is asynchronous or synchronous?JavaScript is Synchronous
Spoiler: at its base, JavaScript is a synchronous, blocking, single-threaded language. That just means that only one operation can be in progress at a time. That's not the entire story, though!
Why is it called asynchronous?In general, asynchronous -- pronounced ay-SIHN-kro-nuhs, from Greek asyn-, meaning "not with," and chronos, meaning "time" -- is an adjective describing objects or events that are not coordinated in time.
Is JavaScript asynchronous programming?JavaScript is a single-threaded, non-blocking, asynchronous, concurrent programming language with lots of flexibility.
|