Hacker News new | past | comments | ask | show | jobs | submit login

Yes, I could include that in my guide. Since promises are actual values, most of the tools in async.js become unnecessary and you can just use whatever you're using for regular values, like your regular array.map / array.reduce functions combined with some promise tools like .all

You already have async.waterfall and async.auto with .then and .spread chaining.

  files.getLastTwoVersions(filename)
    .then(function(items) {
      // fetch versions in parallel
      var v1 = versions.get(items.last),
          v2 = versions.get(items.previous);
      return [v1, v2];
    })
    .spread(function(v1, v2) { 
      // both of these are now complete.
      return diffService.compare(v1.blob, v2.blob)
    })
    .then(function(diff) {
      // voila, diff is ready.
    });
async.map is straightforward.

  // download all items, then get their names
  var pNames = ids.map(function(id) { 
    return getItem(id).then(function(result) { 
      return result.name;
    });
  });
  // wait for things to complete:
  Promise.all(pNames).then(function(names) {
    // we now have all the names.
  });

If you want to wait for the previous item to download first (ala .mapSeries) thats also pretty straightforward: you just need the previous download to complete, then run the next download, then extract the item name, and thats exactly what you express in the code:

  // start with current being an "empty" already-fulfilled promise
  var current = Promise.fulfilled();
  var namePromises = ids.map(function(id) { 
    // wait for the previous download to complete, then get the next
    // item, then extract its name.
    current = current
      .then(function() { return getItem(id); })
      .then(function(item) { return item.name; });
    return current;
  }); 
  Promise.all(namePromises).then(function(names) {
    // use all names here.
  });
The only thing that remains is mapLimit - which is a bit harder to write - but still not that hard:

  var queued = [], parallel = 3;
  var namePromises = ids.map(function(id) {
    // How many items must be complete before fetching the next?
    // The queued, minus those running in parallel, plus one of the parallel slots.
    var minComplete = Math.max(0, queued.length - parallel + 1);
    // when enough items are complete, queue another request
    // for an item, then get the item's name.
    return Promise.some(queued, minComplete)
      .then(function() {
        var download = getItem(id);
        queued.push(download);
        return download;
      }).then(function(item) {
        return item.name;
      });
  });
  Promise.all(namePromises).then(function(names) {
    // use all names here.
  });
  
Is a library needed? Probably, but only for mapLimit.



Awesome, looking forward to your guide.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: