Datsik
Datsik

Reputation: 14824

How can I do multiple async functions (not nested) for performance, but wait for them to finish before proceeding

I've been using Golang for quite some time, but I love writing Javascript so I've switched back, but in Golang you could use sync.WaitGroup to perform multiple goroutines and wait for them to finish, e.g.:

var wg sync.WaitGroup
for _, val := range slice {
   wg.Add(1)
   go func(val whateverType) {
       // do something
       wg.Done()
   }(val)
}

wg.Wait() // Will wait here until all `goroutines` are done 
          // (which are equivalent to async callbacks I guess in `golang`)

So how can I accomplish something like this in Javascript (Node). This is what I'm currently working with:

router.get('/', function(req, res, next) {

   // Don't want to nest
   models.NewsPost.findAll()
   .then(function(newsPosts) {
       console.log(newsPosts);
   })
   .error(function(err) {
      console.error(err);
   });

   // Don't want to nest
   models.ForumSectionPost.findAll({
       include: [
           {model: models.User, include: [
               {model: models.Character, as: 'Characters'}
           ]}
       ]
   })
   .then(function(forumPosts) {
       console.log(forumPosts);
   })
   .error(function(err) {
       console.error(err);
   });

    // Wait here some how until all async callbacks are done
  res.render('index', { title: 'Express' });
});

I don't want to nest each .findAll() into a return for the promise because then they will process in order and cost performance. I'd like them to run together and then wait until all async callbacks are done and then proceed.

Upvotes: 0

Views: 205

Answers (1)

MinusFour
MinusFour

Reputation: 14423

You'll need to use a library that supports Promise.all:

router.get('/', function(req, res, next) {

   // Don't want to nest
   var p1 = models.NewsPost.findAll()
   .then(function(newsPosts) {
       console.log(newsPosts);
   })
   .error(function(err) {
      console.error(err);
   });

   // Don't want to nest
   var p2 = models.ForumSectionPost.findAll({
       include: [
           {model: models.User, include: [
               {model: models.Character, as: 'Characters'}
           ]}
       ]
   })
   .then(function(forumPosts) {
       console.log(forumPosts);
   })
   .error(function(err) {
       console.error(err);
   });

  Promise.all([p1, p2]).then(function(){
     // Wait here some how until all async callbacks are done
     res.render('index', { title: 'Express' });
  });
});

Upvotes: 1

Related Questions