JavaScript Promise Tips & Tricks

Tip 1: Promise Chaining

instead of this,

axios.get('https://jsonplaceholder.typicode.com/posts')
  .then(res => {
    console.log(res.data);
    getPhotos()
      .then(photos => {
        console.log(photos.data)
      })
  })
  .catch(err => {
    console.error(err)
  })

function getPhotos() {
  return axios.get('https://jsonplaceholder.typicode.com/photos');
}

use like this,

axios.get('https://jsonplaceholder.typicode.com/posts')
  .then(res => {
    console.log(res.data);
    return getPhotos();
  })
  .then(res => {
    console.log(res.data);
  })
  .catch(err => {
    console.error(err)
  })

function getPhotos() {
  return axios.get('https://jsonplaceholder.typicode.com/photos');
}

Why?

Readable and easier to understand.

Tip 2: Speed up promises with promise.all()

instead of this,

function getUsersLength() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(['lahin', 'hussain'].length)
        }, 5000);
    })
}

function getPhotosLength() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(['photo 1', 'photo 2'].length)
        }, 6000);
    })
}

async function doSomething() {
  try {
    const usersLength = await getUsersLength();
    const photosLength = await getPhotosLength();
    
    console.log(usersLength, photosLength); // 2, 2
  } catch(err) {
    throw new Error(err);
  }
}

doSomething();

after 11 seconds you can see the result 2, 2.

You should use like this,

function getUsersLength() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(['lahin', 'hussain'].length)
    }, 5000);
  })
}

function getPhotosLength() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(['photo 1', 'photo 2'].length)
    }, 6000);
  })
}

async function doSomething() {
  try {
    const [usersLength, photosLength] = await Promise.all([getUsersLength(), getPhotosLength()]);
    console.log(usersLength, photosLength); // 2, 2
  } catch(err) {
    throw new Error(err);
  }
}

doSomething();

Why?

getUsersLength() took 5 seconds to resolve and getPhotosLength() took 6 seconds to resolve. promise.all() will executes those functions parallelly, so after 6 seconds you can see the result.

Tip 3: await inside for…of and foreach loop

instead of this,

function getUsersTitle() {
  return axios.get('https://jsonplaceholder.typicode.com/users')
     .then(res => res.data.map(({ name }) => name));
}

function makeUppercase(val) {
  return Promise.resolve(val.toUpperCase());
}

async function doSomething() {
  const names = await getUsersTitle();

  names.forEach(async name => {
    const uppercasename = await makeUppercase(name)
    console.log(uppercasename);
  });

  console.log("Finished");
}

doSomething();
// Finished
// LEANNE GRAHAM
// ERVIN HOWELL
// CLEMENTINE BAUCH
// PATRICIA LEBSACK
// CHELSEY DIETRICH
// MRS. DENNIS SCHULIST
// KURTIS WEISSNAT
// NICHOLAS RUNOLFSDOTTIR V
// GLENNA REICHERT
// CLEMENTINA DUBUQUE

Use like this,

function getUsersTitle() {
  return axios.get('https://jsonplaceholder.typicode.com/users')
    .then(res => res.data.map(({ name }) => name));
}

function makeUppercase(val) {
  return Promise.resolve(val.toUpperCase());
}

async function doSomething() {
  const names = await getUsersTitle();

  for(let name of names) {
    const uppercasename = await makeUppercase(name);
    console.log(uppercasename);
  }

   console.log("Finished");
}

doSomething();
// LEANNE GRAHAM
// ERVIN HOWELL
// CLEMENTINE BAUCH
// PATRICIA LEBSACK
// CHELSEY DIETRICH
// MRS. DENNIS SCHULIST
// KURTIS WEISSNAT
// NICHOLAS RUNOLFSDOTTIR V
// GLENNA REICHERT
// CLEMENTINA DUBUQUE
// Finished

Why?

forEach loop can’t process data in sequence.

use for..of to get the data in sequence.

Tip 4: Always better to return promise

Instead of this,

function getUsers() {
  return axios.get('https://jsonplaceholder.typicode.com/users');
}

function getPhotos() {
  return axios.get('https://jsonplaceholder.typicode.com/photos'); // 5000 photos
}

getUsers()
  .then(res => {
    getPhotos()
      .then(photos => {
        console.log(photos.data)
      })
  })
  .then(() => {
    console.log("JS Promise");
  })
  .catch(err => {
    console.error(err);
  })

Use like this,

function getUsers() {
  return axios.get('https://jsonplaceholder.typicode.com/users');
}

function getPhotos() {
 return axios.get('https://jsonplaceholder.typicode.com/photos'); // 5000 photos
}

getUsers()
  .then(res => {
    return getPhotos();
  })
  .then(photos => {
    console.log(photos.data);
  })
  .then(() => {
    console.log("JS Promise");
  })
  .catch(err => {
    console.error(err);
  })

Why?

You can see it prints JS Promise first then prints Photos array, this can be problematic.

Leave a Comment

Your email address will not be published. Required fields are marked *