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.
You already have async.waterfall and async.auto with .then and .spread chaining.
async.map is straightforward. 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: The only thing that remains is mapLimit - which is a bit harder to write - but still not that hard: Is a library needed? Probably, but only for mapLimit.