- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Promises Callbacks And Async/Await
First we have to understand two main concepts
- Synchronous programming
- Asynchronous programming
SYNCHRONOUS PROGRAMMING
It waits for each statement to complete its execution before going to next statement.
This approach can slow down application process if statements are not dependent on each other but still they are waiting for execution as they are in queue.
ASYNCHRONOUS PROGRAMMING
It does not wait for current statement to complete its execution before moving to next statement. e.g. calling a web service and executing file copy in JavaScript.
The call to web service can take some time to return a result meanwhile we can complete some other actions.
Once server provides the result, we can process that without waiting for it.
Our three approaches 1. Callbacks 2. Promises 3. Async/Await handles the asynchronous programming.
CALLBACKS
const articles = [ {title:'First article'}, {title:'Second article'} ]; function getArticles(){ setTimeout(()=>{ let articleContent=''; articles.forEach((article,index)=>{ articleContent+=`${article.title}`+` `; }); console.log(articleContent); },1000); }; getArticles();
Here, we are simply created a article array and printed on console after 1 second.
The use of setTimeout function with 1 second time is just to showcase a behavior like from server.
Now what if we add a new article to the above list through another function
function createArticle(article){ setTimeout(()=>{ articles.push(article); },2000); }
If we now call createArticle with new article and then getArticle we should get three articles but we get only first two articles
const articles = [ {title:'First article'}, {title:'Second article'} ]; function getArticles(){ setTimeout(()=>{ let articleContent=''; articles.forEach((article,index)=>{ articleContent+=`${article.title}`+` `; }); console.log(articleContent); },1000); }; function createArticle(article){ setTimeout(()=>{ articles.push(article); },2000); } createArticle({title:'Third article'}); getArticles(); //console output "First article Second article "
Why is it so?
Because the execution of createArticle has 2 second timeout and in the meantime the getArticle completes its execution
Example
const articles = [ {title:'First article'}, {title:'Second article'} ]; function getArticles(){ setTimeout(()=>{ let articleContent=''; articles.forEach((article,index)=>{ articleContent+=`${article.title}`+` `; }); console.log(articleContent); },1000); }; function createArticle(article, callback){ setTimeout(()=>{ articles.push(article); callback(); },2000); } createArticle({title:'Third article'},getArticles); //console output "First article Second article Third article "
We have nested the call of getArticle inside the createArticle using callback.
Note the passing of getArticles as an argument to createArticle function. But this way, it gets complicated to nest the callbacks
PROMISES
With the use of promises, we dont require to pass callback function. Promises has two arguments resolve and reject. If function executes successfully we can call resolve() else we call reject()
const articles = [ {title:'First article'}, {title:'Second article'} ]; function getArticles(){ setTimeout(()=>{ let articleContent=''; articles.forEach((article,index)=>{ articleContent+=`${article.title}`+` `; }); console.log(articleContent); },1000); }; function createArticle(article){ return new Promise((resolve,reject)=>{ articles.push(article); let isError=false; if(!isError){ resolve(); } else { reject(); } }); } createArticle({title:'Third article'}) .then(getArticles()); //console output "First article Second article Third article " handling error with promises: const articles = [ {title:'First article'}, {title:'Second article'} ]; function getArticles(){ setTimeout(()=>{ let articleContent=''; articles.forEach((article,index)=>{ articleContent+=`${article.title}`+` `; }); console.log(articleContent); },1000); }; function createArticle(article){ return new Promise((resolve,reject)=>{ articles.push(article); let isError=true; if(!isError){ resolve(); }else{ reject('Something went wrong'); } }); } createArticle({title:'Third article'}) .then(getArticles()) .catch(error=>console.log(error)); //console output "Something went wrong"
We called reject from createArticle and caught the error
Promise All
const promise1=Promise.resolve('Hello'); const promise2=100; const promise3=new Promise((resolve,reject)=>{ setTimeout(resolve,2000,'test'); }); Promise.all([promise1,promise2,promise3]) .then((values)=>console.log(values)); //console output ["Hello", 100, "test"]
We can combine the promises in one array and then use actual thenstatement instead of nesting then statements after each promise
we can use fetch api with jsonplaceholder
const promise0=fetch('https://jsonplaceholder.typicode.com/users').then(res=>res.json()); const promise1=Promise.resolve('Hello'); const promise2=100; const promise3=new Promise((resolve,reject)=>{ setTimeout(resolve,2000,'test'); }); Promise.all([promise0,promise1,promise2,promise3]) .then((values)=>console.log(values));
ASYNC / AWAIT
To use await on statement the function should be marked as async
<!DOCTYPE html> <html> <head> <title>Async/Await Example</title> </head> <body> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script type="text/babel"> const articles = [ {title:'First article'}, {title:'Second article'} ]; function getArticles(){ setTimeout(()=>{ let articleContent=''; articles.forEach((article,index)=>{ articleContent+=`${article.title}`+` `; }); console.log(articleContent); },1000); } function createArticle(article){ articles.push(article); } async function testAsync(){ await createArticle({title:'Third article'}); getArticles(); } testAsync(); //console output // First article Second article Third article </script> </body> </html>
testAsync function is marked as async and we used await for createArticle function to complete it first. Then we called getArticles().
Use of async / await are the better version of promises and makes it more clean code