Boyan Iliev

Introduction To JavaScript Promises

Created April 27, 2021

Introduction

A Promise is an object representing the eventual completion or failure of an async operation. A promise is a returned object to which you attach callbacks, instead of passing callback into a function.

new Promise

In order to make a new Promise you need to write new Promise and then it will expect you to pass in a function with two arguments which are functions. The first one represents the resolution of this promise and the second one the rejection of this promise.

const requestPromise = (url) => {
	return new Promise((resolve, rejects) => {
		const delay = Math.floor(Math.random() * (4500)) + 500;
		setTimeout(() => {
			if(delay > 4000) {
				reject('Connection Timeout :(')
			} else {
				resolve(`Here is your fake data from ${url}`)
			}
		}, delay)
	})
}

Now in order to call the function multiple times with different URLs, we need to use the then method. The then method returns data if the async request is returned. But if the operation is failed, we must use the catch method. This is how it should look like:

requestPromise('reddit.com/api/chicken/page1')
    .then(() => {
        console.log('PAGE1 WORKED!!');
        requestPromise('reddit.com/api/chicken/page2')
            .then(() => {
                console.log('PAGE2 WORKED!!');
                requestPromise('reddit.com/api/chicken/page3')
                    .then(() => {
                        console.log('PAGE3 WORKED!!');
                    })
                    .catch(() => {
                        console.log('PAGE3 ERROR!!');
                    })
                    .catch(() => {
                        console.log('PAGE2 ERROR!!');
                    })
            })
            .catch(() => {
                console.log('PAGE1 ERROR!!');
            })
    })	

As you can notice this is very long and repetitive. We can make it shorter and cleaner by using only one catch. In order for this to work, we need to return a promise from within our callback.

requestPromise('reddit.com/api/chicken/page1')
	.then(() => {
	  console.log('PAGE1 WORKED!!');
	  return requestPromise('reddit.com/api/chicken/page2')
	})
	.then(() => {
    console.log('PAGE2 WORKED!!');
    return requestPromise('reddit.com/api/chicken/page3')
	})
	.then(() => {
		console.log('PAGE3 WORKED!!');
	})
	.catch(() => {
		console.log('REQUEST FAILED!');
	})

Promises are resolved and rejected with values.

requestPromise('reddit.com/api/chicken/page1')
	.then((data) => {
	  console.log('PAGE1 WORKED!!');
		console.log(data);           
	  return requestPromise('reddit.com/api/chicken/page2')
	})
	.catch((err) => {
		console.log('REQUEST FAILED!');
		console.log(err);
	})


// IF IT WORKS IT WILL PRINT:
// PAGE 1 WORKED!!
// Here is your fake data from reddit.com/api/chicken/page1

// IF IT DOESN'T WORK:
// REQUEST FAILED!
// Connection Timeout :(

This is coming from a function.

async Functions

A newer and cleaner syntax for working with async code! It's still the same thing as a promise, but it's "prettier". There are two keywords that you need to know.

async keyword

1. Async functions always return a promise
2. If the function returns a value. the promise will be resolved with that value.
3. If the function throws an exception, the promise will be rejected.
async function hello(){   
}
//-> returns a promise even if empty


const sing = async () => {  
}
// -> we can use async arrow functions

Here are some examples:

const login = async (username, password) => {
	if(!username || !password) 
    throw 'Missing Credentials'
	if(password === 'password') 
    return 'Welcome!'
	throw 'Invalid Password'
}

login('demonslayer64')
	.then(msg => {
		console.log('LOGGED IN!')
		console.log(msg)
	})
	.catch(err => {
		console.log('ERROR!')
		console.log(err)
	})

//Returns:
ERROR!
Missing Credentials
login('demonslayer64', 'slayerdemon46')
	.then(msg => {
		console.log('LOGGED IN!')
		console.log(msg)
	})
	.catch(err => {
		console.log('ERROR!')
		console.log(err)
	})

//Returns:
ERROR!
Invalid Password
login('demonslayer64', 'password')
	.then(msg => {
		console.log('LOGGED IN!')
		console.log(msg)
	})
	.catch(err => {
		console.log('ERROR!')
		console.log(err)
	})

//Returns:
LOGGED IN!
WELCOME!

await keyword

1. The await keyword is used inside of functions declared with async.
2. await will pause the execution of the function, waiting for a promise to be resolved.

Here is an example with our function from earlier:

Checkout our latest product - the ultimate tailwindcss page creator 🚀
async function makeTwoRequests() {
	let data1 = await requestPromise('/page1');
	console.log(data1);
}

//Returns
<- >Promise {<pending>}
Here is your fake data from /page1

Conclusion

This is pretty much the basics of JavaScript promises. Let me know if this has helped you at all. Any feedback will be greatly appreciated!