I have a roughly following code (meta CoffeeScript):
xml = new ...
Promise.promisifyAll xml
allRecords = []
xml.on 'frequentTag', (item) ->
...
iPromise = /* some promise made from item */
allRecords.push iPromise
xml.onAsync('end').then -> Promise.settle allRecords
And now the question: can I get rid of allRecords accumulator?
A promise represents a single value. It's one value.
There is no trivial way to promisify an event emitter since it does not offer a standard contract like node style callbacks for a single value - since different events get called multiple times.
Doing Promise.promisifyAll on an EventEmitter will simply not produce meaningful results on its own, and you'd have to promisify it manually. The good news is that if you happen to do this often you can either extract it to a function yourself or use Bluebird's promisifyAll with a promisifier argument and have it do the traversal for you.
Bluebird has no knowledge of your event emitter and the contract it defines about when callbacks are called and how. Assuming it ends with an end event, errors with an error event data flows in with a frequentTag event - I'd do something like:
xmlProto.prototype.getTags = function getTags(){
// if you do this very often, this can be faster
return new Promise(function(resolve, reject){
var results = [];
this.on("error", reject);
this.on("frequentTag", function(item){
iPhomise = /* some promise made from item */
results.push(iPromise);
});
this.on("end", resolve.bind(null, results));
}.bind(this)).settle(); // settle all
};
Where xmlProto is whatever you're newing, this would let you do:
xml = new ...
xml.getTags().then(function(records){
// work with records
});
This can be extracted into a general function for this sort of event emitter - but you get the general idea.