Skip to content

Instantly share code, notes, and snippets.

@willrstern
Last active February 3, 2021 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save willrstern/af3a3308fc5864cf48f8 to your computer and use it in GitHub Desktop.
Save willrstern/af3a3308fc5864cf48f8 to your computer and use it in GitHub Desktop.
JAVASCRIPT AND ASYNC OPERATIONS 2: Parallel Sequence

##Example Task: Make 2 parallel (simultaneous) async calls, then one async call when they've resolved##

##The Good Way: Promises##

//with bluebird library
var parallelCalls = [
  getUrl('/api/profile'),
  getUrl('/api/accounts')
];
//spread is like .then(), except it apply()s the array of responses as individual arguments
Promise.all(parallelCalls).spread(function(profile, accounts) {
  return getUrl('/api/messages/' + profile.id);
}).then(function(messages) {
  console.log('GOT MESSAGES', messages);
}, function(errs) {
  //handle errors
});

##The Best Way: With Generators##

// with Co (no yieldHandler is required)
co(function* () {
  var [profile, accounts] = yield [
    getUrl('/api/profile'),
    getUrl('/api/accounts'),
  ]; //run both now, wait till both have resolved
  console.log('done', yield getUrl('/api/messages/' + profile.id));
})(function(err) {
  if (err) { console.log('err', err); }
});
// with bluebird
//add a yieldHandler somewhere in your config, so yielded arrays are treated as .all()'s
Promise.coroutine.addYieldHandler(function(yieldedValue) {
  if (Array.isArray(yieldedValue)) return Promise.all(yieldedValue);
});

Promise.coroutine(function* () {
  var [profile, accounts] = yield [
    getUrl('/api/profile'),
    getUrl('/api/accounts'),
  ]; //our custom yield handler will handle this just like co...waiting till both have resolved
  console.log('done', yield getUrl('/api/messages/' + profile.id));
})().catch(function(errs) {
  //handle errors on any events
})

Q...I don't like this way of having to do things, mixing promises feels like kluge

// with Q - hopefully somebody can correct me with a better way
Q.spawn(function* () {
  try {
    var signin = getUrl('/api/profile');
    var profile = getUrl('/api/accounts');
    var signinAndProfile = yield Q.all([signin, profile]); //run both now, wait till both have resolved
    console.log('done', yield getUrl('/api/messages/' + signinAndProfile[0].id));
  } catch(errs) {
    //handle any errors
  }
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment