Introduction To JavaScript Promises
Tags: javascript, async, developer
Published: 2021-04-27 15:23:09

# 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:

```
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!