James111 James111 - 6 months ago 14
Javascript Question

Nesting promises for a parallel effect?

I've had to nest a promise within a promise, is this okay, or considered bad practise?


  1. I've a class which has a method,
    fetchArticles
    ,
    fetchImages
    , and
    main
    .


    • The
      main
      is the one which calls
      fetchArticles
      +
      fetchImages

    • fetchArticles
      runs a function from another file which returns a promise, but I'm also returning a promise on the
      fetchArticles
      class method itself, so when it's fetched the articles, it will go ahead and fetch the images.

    • fetchImages
      method is not promised but calls a promised function from another file.




I'm unsure if this is the best way to achieve a parralel effect?

main () {
// Call the promised fetchArticles class method
this.fetchArticles()
.then ( () => this.fetchImages( () => {
this.res.json(this.articles.data);
}));
}


fetchArticles () {
return new Promise ((fullfil, rej) => {
// Calling a promised function which simply returns an array of articles
fetchArticles (this.parametersForApiCall)
.then ( (data) => {
this.articles.data = data;
this.articles.imageIds = [1,5,2,8,99,1000,22,44,55,120,241]; // Extract image IDS and save to class this
fullfil();
})
.catch ( (err) => {
console.log ("Something went wrong with api call", err);
res.json({error: "Something went wrong", code: 1011});
reject();
});
});
}

fetchImages (cb) {
// Calling a promised function which simply returns an array of images
fetchImages (this.imageIds).then( (imgs) => {
this.images = imgs;
cb (); // Temp callback method
}).catch ( (err) => {
console.log (err, "error finding images in then")
})
}
}


Should I use something like async parallel? Note I've added a
callback
in the
fetchImages
method temporarily until I find a good solution for chaining promises.

Answer

A few notes:

  1. you are creating an unnecessary promise in your fetchArticles function. You can return the result of the promisified fetchArticles directly.

  2. Using Promise.all will let you fire off both items simultaneously. If your two methods aren't dependent on each other then this is a good way to go. I've updated the main function with that code.

  3. Similarly, you can return the promise directly in your fetchImages function. Because this is also promisified, you no longer need the callback. I've removed it.

The resulting code

main () {
    // Call the promised fetchArticles and fetchImages class methods
    Promise.all([this.fetchArticles(), this.fetchImages()])
      .then(() => this.res.json(this.articles.data));
}


fetchArticles () {
  // Calling a promised function which simply returns an array of articles
  return fetchArticles (this.parametersForApiCall)
    .then ( (data) => {
      this.articles.data = data;
      this.articles.imageIds = [1,5,2,8,99,1000,22,44,55,120,241]; // Extract image IDS and save to class this
    })
    .catch ( (err) => {
      console.log ("Something went wrong with api call", err);
      res.json({error: "Something went wrong", code: 1011});
      reject();
    });
}

fetchImages () {
    // Calling a promised function which simply returns an array of images
    return fetchImages (this.imageIds).then( (imgs) => {
      this.images = imgs;
    }).catch ( (err) => {
      console.log (err, "error finding images in then")
    })
  }
}