0% found this document useful (0 votes)
145 views5 pages

Sync vs Async in JavaScript Explained

The document discusses promises and asynchronous code execution in JavaScript. It defines synchronous code as executing tasks one after another in a blocking manner, while asynchronous code allows subsequent tasks to run concurrently without waiting. Promises are used to handle asynchronous operations and return immediately rather than waiting for the operation to complete. They are constructed with resolve and reject functions to handle success and failure respectively. When a promise is returned, its then method allows registering callback functions to handle the operation outcome asynchronously.

Uploaded by

Kiran Gali
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
145 views5 pages

Sync vs Async in JavaScript Explained

The document discusses promises and asynchronous code execution in JavaScript. It defines synchronous code as executing tasks one after another in a blocking manner, while asynchronous code allows subsequent tasks to run concurrently without waiting. Promises are used to handle asynchronous operations and return immediately rather than waiting for the operation to complete. They are constructed with resolve and reject functions to handle success and failure respectively. When a promise is returned, its then method allows registering callback functions to handle the operation outcome asynchronously.

Uploaded by

Kiran Gali
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Promises

To understand promises, it is necessary to first understand the distinction between


asynchronous and synchronous code execution.

Sync vs Async Code:

We will now create a function that simulates a database call by running a large loop and
printing "how are you?" at the end.
function fakeDatabase()
{
var sum = 0
for(var i = 0;i<1000000000;i++)
{
sum = sum + 1
}

[Link]("How are you ?");


}

In the following code example, we will invoke the fakeDatabase function and then log a
message to the console
fakeDatabase() // first execution
[Link]("Hi"); // second execution

The following execution log demonstrates synchronous code execution. The code
began running at [Link], first computing the fakeDatabase function to print "how are
you?", and then moving on to the next statement "Hi" at [Link].
PS C:\Users\kirangali\Desktop\node_js_learning> node .\promises_exp.js
12/29/2022, [Link] AM
How are you ?
12/29/2022, [Link] AM
Hi
In this case, the code is considered synchronous because it executes tasks one after
the other in a blocking manner. This means that the processor will wait for the database
call to finish before moving on to the next statement.

Asynchrnous Code:

Asynchronous code or Async code is in contrast to synchronous, executes the console


log “Hi” while the cpu computes/works on the fakeDatabaseCall.

asyncfakeDatabase().then(onSuccess, onFailure)
[Link]("Hi")

PS C:\Users\kirangali\Desktop\node_js_learning> node .\promises


Hi
How are you?
PS C:\Users\kirangali\Desktop\node_js_learning>

It is important to note that the onsuccess and onfailure methods should not be a source
of confusion at this point. So don’t worry about them. Your understanding should simply
be that the processor executes the second statement "Hi" while the database call is
being processed and the data is being returned.

You may have questions such as:


● Why did the processor move on to the next statement instead of waiting for the
database call to finish?
● How does the CPU know to move on to the next statement?
● When does the processor actually find out that the database call has finished and
it needs to process the returned data?

So the idea is , asyncfakeDatabase returns a promise first instead of


returning the actual data from database.

Let’s write the function step by step to understand it better

Step1 : declare the promise inside a function, by default Promise takes


resolve and reject as parameters.
function asyncfakeDatabase(){
var promise = new Promise((resolve, reject)=>{

});
return promise
}

Step2: write the core logic inside promise construct


function asyncfakeDatabase()
{
var promise = new Promise((resolve, reject)=>{

var sum = 0
for(var i = 0;i<545454548;i++)
{
sum = sum + 1
}

});
return promise
}

Step3:
Now, it is time to explore the use of resolve and reject. Resolve is used to successfully
complete a promise, while reject is used to terminate a promise with an error. In this
case, since the database call is fake, we will use resolve to successfully complete the
promise if the sum of the loop is even, or reject to terminate the promise with an error if
the sum is odd.

function asyncfakeDatabase()
{
var promise = new Promise((resolve, reject)=>{

var sum = 0
for(var i = 0;i<545454548;i++)
{
sum = sum + 1
}

if (sum%2==0)
{
resolve("How are you?")
}
else{
reject("Failed to get data from DB")
}
});
return promise
}

Finally, we will now get into the part where we call this aysnc DB function and handle the
promise.

asyncfakeDatabase().then(onSuccess,onFailure)
[Link]("Hi")

The above two lines can also be written as

databasePromise = asyncfakeDatabase()
[Link](onSuccess, onFailure)
[Link]("Hi")

DB call returned a promise and promise has then method on it by default which takes
two functions as parameters.

We declared those functions

function onSuccess(resolve)
{
[Link](resolve);
//you can do something else as well here
}

function onFailure(reject)
{
[Link](reject)
//you can do something else as well here
}

If the promise was resolved, the onSuccess function will be called, and if the promise
was rejected, the onFailure function will be called.
Further reading:
In the above example, we rejected the promise if the sum was an odd number. In reality,
we may reject the promise if the database does not return the query result within a
certain time frame, which is known as setting a timeout on the promise.

Link for the above code:

Common questions

Powered by AI

In promise construction, resolve is a function called when the operation completes successfully, while reject is called when an error occurs or the operation fails. In the provided function asyncfakeDatabase, resolve is called if the computed sum from a loop is even, indicating success, prompting it to log 'How are you?'. Conversely, reject is called if the sum is odd, simulating an error condition, and logging 'Failed to get data from DB' . This demonstrates how resolve and reject determine the control flow based on the outcome of the operation .

Returning a promise allows code execution to continue without waiting for the asynchronous task to complete. The promise acts as a placeholder for the result of the operation, completing successfully by calling resolve or failing with reject. This enables non-blocking execution as seen when 'Hi' is printed immediately, while the task represented by the promise completes later . This is useful in managing tasks that might take an unknown amount of time, keeping the rest of the application responsive .

Failure to properly handle rejected promises can lead to unhandled promise rejections, which may crash the application or create unreliable software behavior. This is particularly concerning in critical applications where data integrity or user trust is paramount. Such issues may result in memory leaks, unresponsive features, or security vulnerabilities, underlining the importance of defining appropriate error handling, as demonstrated with onFailure in the example code .

Control flow with promises and then() is managed by chaining asynchronous operations. The then() method is invoked on a promise to define actions for fulfillment and rejection, accepting two callback functions. In the example, asyncfakeDatabase().then(onSuccess, onFailure) binds onSuccess to execute if resolve is called, thereby printing the resolved value, and onFailure if reject is called, which logs the rejection reason. This setup allows the asynchronous function's results to dictate subsequent actions, effectively managing control flow .

Asynchronous database calls are preferred in high-load scenarios because they allow the server to handle multiple requests without waiting for each operation to finish, thus enabling higher concurrency and better use of system resources. Synchronous operations block execution, limiting throughput and potentially causing performance bottlenecks. With promises managing asynchronous database interactions, the server remains responsive, handling other requests or tasks in parallel .

Non-blocking execution is crucial in modern web applications because it prevents the UI from freezing while waiting for potentially slow operations like network requests or data processing. Promises facilitate this by allowing the application to continue executing other tasks while waiting for an asynchronous operation to complete. When the promise settles, registered callbacks with then() execute the needed operations based on success or failure, ensuring responsiveness and better user experience .

Promises and async/await syntax provide a more straightforward and readable way to handle asynchronous operations compared to traditional callbacks. Async/await allows developers to write asynchronous code that appears synchronous, thus reducing callback hell and improving comprehension. Promises underlie async/await, providing a robust framework for error handling and chaining operations. This approach ensures cleaner code, simplified handling of promise resolutions and rejections, and less overhead in managing asynchronous control flow .

To enhance readability and maintainability, developers should use clear, descriptive names for promise-related functions, separate promise creation from handling by using functions like async/await, and avoid nesting then() excessively by using chaining or async functions. Consistent error handling with .catch() or finally(), along with using library utilities for common patterns, can streamline complex asynchronous logic, making code easier to understand and debug .

Synchronous code execution processes tasks one at a time, in a blocking manner. This is demonstrated in the example with the function fakeDatabase, where the console logs 'How are you?' after the loop completes before proceeding to log 'Hi' . In contrast, asynchronous code execution allows tasks to occur out of order, without waiting for each to complete. This is demonstrated with asyncfakeDatabase, where 'Hi' is logged before 'How are you?' because the async function returns a promise, allowing the processor to move on before checking the promise status .

In real-world applications, promises may be rejected for several reasons including network failures, server errors, invalid input data, or timeouts when a database query doesn't return results within a certain timeframe . Unlike the example where an odd sum triggers rejection, these scenarios involve actual operational failures or constraints, ensuring that potential errors in asynchronous operations are handled efficiently, maintaining the robustness of the application .

You might also like