Javascript is an asynchronous programming language. the main reason why its asynchronous because it is also single threaded.
you can use Webworkers to utilise more then one threads at a time.
What is asynchronous Programming:
In programming, the term asynchronous refers to code that doesn't block the main program flow while waiting for long-running operations to complete. This is in contrast to synchronous code, which executes line by line and waits for each operation to finish before moving on.
Why do we need it:
Suppose we're making an api call to the server which takes 5 second of time, now instead of waiting for 5 seconds we can do some other computations like showing
In programming languages like javascript which is single treaded it means it can only utilise one thread at ones, so you would have to wait for code to execute line by line, which can increase wait time since we can only run one process at a time.
That's why javascript is Asynchronous
Let's understand promises and how to implement them in javascript, we will talk about how we use promises and async/await to do our asynchronous operations.
Promises
Has someone ever made a promise to you?
Promises in JavaScript are similar to that. When a promise is made, it represents a value that may be available now, in the future, or never.
A promise in JavaScript can be in one of three states:
- Pending: Initial state, neither fulfilled nor rejected.
- Fulfilled: The operation completed successfully.
- Rejected: The operation failed.
Here's an example of a promise:
let promise = new Promise((resolve, reject) => {
// Simulate an asynchronous operation using setTimeout
setTimeout(() => {
let result = true; // Simulating result positive value
if (result) {
resolve("Promise fulfilled!");
} else {
reject("Promise rejected!");
}
}, 1000);
});
promise
.then((message) => {
console.log(message); // Logs "Promise fulfilled!" if the promise is resolved
})
.catch((error) => {
console.log(error); // Logs "Promise rejected!" if the promise is rejected
});
Here is a simple breakdown of above code:
1. Creating a Promise:
let promise = new Promise((resolve, reject) => {...});- This line creates a new Promise object named
promise. - The
Promiseconstructor takes an executor function with two arguments:resolveandreject.
- This line creates a new Promise object named
2. Simulating Asynchronous Operation:
setTimeout(() => {...}, 1000);- Inside the executor function, a
setTimeoutfunction is used to simulate an asynchronous operation (suppose we are making an api call and it is taking 1 second) - This function delays the execution of the code inside it for 1 second (1000 milliseconds).
- The anonymous function passed to
setTimeoutwill be executed after the delay.
- Inside the executor function, a
3. Resolving or Rejecting the Promise:
let result = true; // Let's assume our api returned positive response like 201- A variable
resultis declared and assigned a value (here,true). This simulates the outcome of the asynchronous operation.
- A variable
if (result) { resolve("Promise fulfilled!"); } else { reject("Promise rejected!"); }- An if-else statement checks the value of
result.- If
resultis truthy (here,true), theresolvefunction is called with the message "Promise fulfilled!". This indicates successful completion of the asynchronous operation. - If
resultis falsy, therejectfunction is called with the message "Promise rejected!". This indicates an error occurred during the operation.
- If
- An if-else statement checks the value of
4. Handling Promise Resolution/Rejection:
promise.then((message) => {...}, .catch((error) => {...});- After creating the promise, the
.thenand.catchmethods are chained to handle its outcome. .thentakes a callback function that executes if the promise is resolved. Here, it logs the message received throughresolve("Promise fulfilled!")..catchtakes a callback function that executes if the promise is rejected. Here, it logs the error message received throughreject("Promise rejected!").
- After creating the promise, the
This is how you do Promises in javascript now let's talk about Async/await
Async await
In javascript async await is just a better way of doing promises, it gives us better syntax and its easier to understand
Let's see the example of promises
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: 'John Doe', age: 30 };
resolve(data); // Simulating successful data fetching
}, 2000);
});
};
const displayData = async () => {
try {
console.log('Fetching data...');
const data = await fetchData(); // Wait for the promise to resolve
console.log('Data:', data);
} catch (error) {
console.error('Error:', error);
}
};
displayData();
Let's break down the above code
1. Asynchronous Function (displayData):
const displayData = async () => { ... }- The
asynckeyword before the function declaration marksdisplayDataas an asynchronous function. - Asynchronous functions implicitly return a promise.
- The
2. Error Handling (try...catch):
try { ... } catch (error) { ... }- A
try...catchblock is used to handle potential errors during the asynchronous operation.- Code within the
tryblock is executed. If an error occurs, it's caught by thecatchblock.
- Code within the
- A
3. await Keyword:
const data = await fetchData();- The
awaitkeyword is used inside thetryblock. - It pauses the execution of
displayDatauntil the promise returned byfetchData()is either resolved or rejected.
- The
4. Promise Resolution:
- When
fetchData()'s promise resolves (after 2 seconds), the value it resolves with (thedataobject) is assigned to thedatavariable. - Execution continues to the next line (
console.log('Data:', data);), logging the fetched data.
5. Promise Rejection (If Any):
- If
fetchData()'s promise were to be rejected (e.g., due to a network error), thecatchblock would be executed. - The
errorobject would contain information about the rejection, which is then logged to the console.
In essence, async/await provides a more synchronous-looking way to handle asynchronous operations in JavaScript, making code easier to read and reason about.
Conclusion:
Both Promises and Async/Await are powerful tools for dealing with asynchronous operations in JavaScript. Promises provide a structured way to handle the eventual success or failure of these operations. Async/Await builds upon Promises, offering a more readable and intuitive syntax that resembles synchronous code.
Choose Promises when:
- You need a more fundamental way of working with asynchronous code.
- You're dealing with older browsers that might not fully support Async/Await.
Choose Async/Await when:
- You want a cleaner and more synchronous-like coding style.
- Error handling and sequential asynchronous operations are a priority.
At the end it all depends on your project's needs and your preference as a developer.
