Serial Promises vs Parallel Promises 
Tags: javascript
Published: 2019-03-30 14:43:39

---
title: Serial Promises vs Parallel Promises 
published: true
description: examples of when to use Promise.all instead of writing serial code
tags: javascript
---

In javascript we often need to do multiple asynchronous things.

 I'd like to use this post to show a few examples of doing things serially, and in parallel with promises.

## Example 1: "Wait a second" x 3

First example, lets define a function where we "wait a second", three times in a row.

This function will be called serial.

After that, we'll call the "wait a second" function, three times in parallel

This function will be called parallel

```javascript
function wait(waitTime) {
  return new Promise(resolve => setTimeout(() => {
    console.log(`waited ${waitTime} ms`)
    resolve()
  }, waitTime));
}

async function serial() {
  console.time('serial');
  await wait(1000);
  await wait(1000);
  await wait(1000);
  console.timeEnd('serial');
}

async function parallel() {
  console.time('parallel');
  await Promise.all([
    wait(1000),
    wait(1000),
    wait(1000)
  ])
  console.timeEnd('parallel');
}


async function test() {
  await serial();
  await parallel();
}

test();
```



### Output
```
waited 1000 ms
waited 1000 ms
waited 1000 ms
serial: 3016.319ms
waited 1000 ms
waited 1000 ms
waited 1000 ms
parallel: 1003.017ms
```

From the output we can see Promise.all enables us to do all of the "wait a second" calls at the same time.

## Example 2: Add two async numbers
In the previous example, we just waited a second. In this example we'll get two numbers asynchronously and add them together, serially and in parallel.

```javascript
function randomNumber() {
  const rand = Math.random() * 100;
  return new Promise(resolve => setTimeout(() => {
    resolve(rand)
  }, 1000))
}

async function addExampleSerial() {
  console.time('add-serial');
  const number1 = await randomNumber();
  const number2 = await randomNumber();
  const result = number1 + number2;
  console.timeEnd('add-serial');
  console.log('serial result: ', result);
}


async function addExampleParallel() {
  console.time('add-parallel');
  const [number1, number2] = await Promise.all([randomNumber(), randomNumber()]);
  const result = number1 + number2;
  console.timeEnd('add-parallel');
  console.log('parallel result: ', result);
}

async function test() {
  await addExampleSerial();
  await addExampleParallel();
}

test();
```

### Output
```
add-serial: 2005.019ms
serial result: 59.0316729944722
add-parallel: 1000.616ms
parallel result: 48.7190841367634
```

## Example 3: Required Data Dependencies

In the last example, we had to add numbers which were returned asynchronously, but we still haven't had an example where an asynchronous value is required before another asynchronous value could be retrieved.

In this example, we'll get our username, and then we'll fetch two pieces of information which depend on our username.

```javascript
function fetchData(data) {
  return new Promise(resolve => setTimeout(() => {
    resolve(data)
  }, 1000))
}

function getLoggedInUser() {
  return fetchData('user1');
}

async function getDataForUser(userName) {
  const profileData = await fetchData({
    user1: {name: 'Micah', points: 100},
    user2: {name: 'someone else', point: 200}
  });
  return profileData[userName];
}

async function getUserPosts(userName) {
  const posts = await fetchData({
    user1: ['Promises Post'],
    user2: ['Streams Post']
  });
  return posts[userName];
}

async function userDataSerial() {
  console.time('userData-serial');
  const userName = await getLoggedInUser();
  const userData = await getDataForUser(userName);
  const userPosts = await getUserPosts(userName);
  console.timeEnd('userData-serial');
}


async function userDataParallel() {
  console.time('userData-parallel');
  const userName = await getLoggedInUser();
  const [userData, userPosts] = await Promise.all([
    getDataForUser(userName),
    getUserPosts(userName)
  ])
  console.timeEnd('userData-parallel');
}

async function test() {
  await userDataSerial();
  await userDataParallel();
}

test();
```


### Output
```
userData-serial: 3007.785ms
userData-parallel: 2006.665ms
```
## Conclusion

In order to optimize your code for speed, pay attention to which data is required to make calls, and then structure your code to where as many of those dependencies are fetched in parallel as possible with Promise.all()

Note: At some point, you may attempt to do too many async things at once. Now you've got to determine how many you can do, and create batches of that size to prevent thrashing. That's a post for another time.