Dynamic or conditional based Promise.all() and destructing

41 Views Asked by At

I want to get data from DB based on the boolean flag.

async function main() {
  let promises = [];

  if (false) {
    promises.push(Promise.resolve("highlights from DB"));
  }

  if (true) {
    promises.push(Promise.resolve("featured video from DB"));
  }

  if (true) {
    promises.push(Promise.resolve("categories from DB"));
  }

  const [highLightVideo, featuredVideo, categories] = await Promise.all(promises);

  console.log("highLightVideo: ", highLightVideo);
  console.log("featuredVideo: ", featuredVideo);
  console.log("categories: ", categories);
}

main();

Above code output:

highLightVideo:  featured video from DB
featuredVideo:  categories from DB
categories:  undefined

Output I need:

highLightVideo:  undefined
featuredVideo:  featured video from DB
categories:  categories from DB

Note: (Solution that won't work for me because of project structure)

  • I cannot use .then() flow.
  • I cannot return any custom value like this promises.push(Promise.resolve({ msg: "highlights from DB", type: 'HIGHLIGHT' }));
2

There are 2 best solutions below

1
AKX On

Just push a resolved promise of undefined for the things you don't care about, so the length of promises is always 3 and you can destructure it in a constant way:

const undefinedPromise = Promise.resolve(undefined);

async function getThings(highlights, featured, categories) {
  const promises = [];

  if (highlights) {
    promises.push(Promise.resolve("highlights from DB"));
  } else {
    promises.push(undefinedPromise);
  }

  if (featured) {
    promises.push(Promise.resolve("featured video from DB"));
  } else {
    promises.push(undefinedPromise);
  }

  if (categories) {
    promises.push(Promise.resolve("categories from DB"));
  } else {
    promises.push(undefinedPromise);
  }
  return Promise.all(promises);
}

console.log(await getThings(true, false, true));
console.log(await getThings(false, true, true));
console.log(await getThings(true, true, true));

0
Alexander Nenashev On

You can resolve any static value with Promise.all(). In this option empty values will be equal false:

function getThings(highlights, featured, categories) {
  return Promise.all([
    highlights && Promise.resolve("highlights from DB"),
    featured && Promise.resolve("featured video from DB"),
    categories && Promise.resolve("categories from DB")
  ]);
}

(async()=>{
console.log(await getThings(true, false, true));
console.log(await getThings(false, true, true));
console.log(await getThings(true, true, true));
})();

If you want exact undefined:

function getThings(highlights, featured, categories) {
  return Promise.all([
    highlights ? Promise.resolve("highlights from DB") : undefined,
    featured ? Promise.resolve("featured video from DB") : undefined,
    categories ? Promise.resolve("categories from DB") : undefined
  ]);
}

(async()=>{
console.log(await getThings(true, false, true));
console.log(await getThings(false, true, true));
console.log(await getThings(true, true, true));
})();