Promise, Async/Await, Generators
Promise
In JavaScript, a promise is an object representing the eventual completion or failure of an asynchronous operation and its resulting value. Promises are a way to handle asynchronous operations more elegantly than using callbacks. (We can use Promise to avoid the case of callback hell) They provide a cleaner and more readable syntax for dealing with asynchronous code.
A promise can be in one of three states:i) Pending
The initialstate, The promise is neither fulfilled nor rejected.ii) Resolved (Fulfilled)
The operation completed successfully, and the promise has a resulting value.iii) Rejected (Failed)
The operation failed, and the promise has a reason for the failure.const myPromise = new Promise((resolve, reject) => { // Asynchronous operation (e.g., fetching data from an API) setTimeout(() => { const success = true; if (success) { // If the operation is successful, call resolve with the result resolve("Operation completed successfully"); } else { // If the operation fails, call reject with the reason reject("Operation failed"); } }, 1000); // Simulating an asynchronous operation that takes 1 second }); // Handling the promise myPromise .then((result) => { // If the promise is fulfilled, this callback is executed console.log(result); }) .catch((error) => { // If the promise is rejected, this callback is executed console.error(error); });
In this example,
resolve
is a function that is called when the asynchronous operation is successful, andreject
is called when it fails.
The.then()
method is used to handle the fulfilled state,
The.catch()
method is used to handle the rejected state.
Promises provide a more structured and readable way to work with asynchronous code compared to traditional callback-based approaches. Additionally, they allow you to chain multiple asynchronous operations together in a more concise manner.Fetch
In JavaScript, thefetch
function is used to make network requests, typically to retrieve resources from a server. It returns a Promise that resolves to theResponse
to that request, whether it is successful or not.
Here's a basic example of usingfetch
to make a simple GET request,fetch('https://api.example.com/data') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); // This returns a Promise }) .then(data => { // Handle the data console.log(data); }) .catch(error => { // Handle errors console.error('Fetch error:', error); });
If you need to make a POST request or include headers, you can provide additional options to the
fetch
function,fetch('https://api.example.com/post-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/json', // Other headers as needed }, body: JSON.stringify({ key1: 'value1', key2: 'value2', }), }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Fetch error:', error));
Remember that the
fetch
API is asynchronous, so it works well with Promises and can be combined with async/await for more readable code.Axios
Axios is a popular JavaScript library that is used for making HTTP requests. It is commonly used in both browser and Node.js environments. Axios provides a simple and clean API for performing asynchronous HTTP requests.i) Install Axios
You can install Axios using npm or include it directly in your HTML file.
npm install axios
Or include it directly in your HTML file,
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
ii) Using Axios
// Make a GET request axios.get('https://jsonplaceholder.typicode.com/posts/1') .then(response => { // Handle successful response console.log(response.data); }) .catch(error => { // Handle error console.error(error); });
Axios supports other HTTP methods like
post
,put
, anddelete
as well. In Axxios POST parameters are send as a second argument where as the first argument will be always a API call.
Axios provides a clean promise-based API, making it easy to work with asynchronous requests. It also has features like request and response interceptors, automatic transformation of JSON data, and more.Remember to handle promises properly using
.then()
for successful responses and.catch()
for errors. Additionally, Axios allows for configuration options, such as headers, timeout, and more, which can be specified in the request.Async/Await
Async/await is a feature in JavaScript that allows you to work with asynchronous code in a more synchronous-looking manner. It provides a more readable and concise way to handle promises.i) Async Function Declaration
To use
async
/await
, you declare a function with theasync
keyword.An async function always returns a promise, and the value of the promise will be whatever the async function returns.
async function myAsyncFunction() { // Code here }
ii) Await Expression
Inside an async function, you can use theawait
keyword before a promise. It pauses the execution of the function until the promise is resolved and returns the resolved value.async function example() { const result = await someAsyncFunction(); console.log(result); }
Here's a simple example illustrating the use of async/await with a Promise,
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function asyncFunction() { console.log("Start"); await delay(2000); console.log("After 2 seconds"); } asyncFunction();
In this example,
asyncFunction
logs "Start," then waits for 2 seconds usingawait delay(2000)
before logging "After 2 seconds." The asynchronous delay function returns a promise that resolves after the specified time. The use ofawait
makes the asynchronous code look more like synchronous code.Here's a simple example illustrating the use of async/await with a Fetch,
const url = 'http://abcd.com/movies'; const postParams = { 'MessageHeader':{ 'ProtocolVersion' : "3.0", 'MessageClass' : "Service", 'MessageCategory' : "Abort", 'MessageType' : "Request", } }; const post = async fetch(url, postParams) => { const response = await fetch(url, { method: 'POST', body: JSON.stringify(postParams), headers: { 'Content-type': 'application/json; charset=UTF-8', 'x-API-key': postAPiKey } }); console.log(response); } // Then use it like so with async/await: (async () => { const data = await post(postAPiUrl, postParams); console.log(data) })();
Difference between Promises and Async/Await
Promises and async/await are both mechanisms in JavaScript for handling asynchronous operations, but they have different syntax and usage patterns.
Promises
i) It's an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
ii) Promises have a chaining mechanism which makes them great for sequential asynchronous operations.
iii) Promises use.then()
and.catch()
methods to handle success and failure respectively.someAsyncOperation() .then(result => { console.log(result); }) .catch(error => { console.error(error); });
function fetchDataWithPromise() { return new Promise((resolve, reject) => { setTimeout(() => { const data = { message: "Data fetched successfully!" }; // Simulate success resolve(data); // Simulate failure // reject(new Error("Failed to fetch data")); }, 2000); }); } fetchDataWithPromise() .then(result => { console.log("Promise Example:", result); }) .catch(error => { console.error("Promise Example Error:", error); });
Async/Await
i) Async functions enable writing asynchronous code that looks synchronous, making it easier to understand and maintain.
ii) Async functions always return a promise, and the value the promise is resolved with in the return value of the async function.
iii) Theasync
keyword is used to define an asynchronous function, and theawait
keyword is used to pause the execution of an async function until a promise is settled.
iv) Async/await is particularly useful for handling asynchronous operations in a more synchronous-looking code flow, making it easier to reason about.async function someAsyncOperation() { try { let result = await fetchSomeData(); console.log(result); } catch (error) { console.error(error); } } someAsyncOperation();
async function fetchDataWithAsyncAwait() { try { const response = await fetchDataWithPromise(); console.log("Async/Await Example:", response); } catch (error) { console.error("Async/Await Example Error:", error); } } fetchDataWithAsyncAwait();
In summary, promises provide a way to deal with asynchronous operations by allowing you to handle success and failure with
.then()
and.catch()
, while async/await offers a more concise and synchronous-looking syntax for working with promises, making asynchronous code easier to read and write. Async/await builds upon promises and provides a cleaner way to handle asynchronous operations, especially when dealing with multiple asynchronous operations or complex control flow.