I have some good news and some bad news.
Very good! You have found out the problem with the notifications API and why it is being removed in Q in the v2 branch, being deprecated in newer libraries like Bluebird, and never included in ECMAScript 6. It really boils down to the fact promises are not event emitters.
The notifications API does not compose or aggregate very well. In fact, notifications being on promises does not make too much sense imo to begin with,.
Instead, I suggest using a progress notification even, kind of like IProgress in C#. I'm going to simulate all the actions with Q.delay()
for isolation, your code will obviously make real calls
function connect(iProgress){
return Q.delay(1000).then(function(res){
iProgress(0.5,"Connecting to Database");
}).delay(1000).then(function(res){
iProgress(0.5,"Done Connecting");
});
}
function send(data,iProgress){
return Q.delay(200*Math.random() + 200).then(function(res){
iProgress(0.33, "Sent First Element");
}).delay(200*Math.random() + 400).then(function(){
iProgress(0.33, "Sent second Element");
}).delay(200*Math.random() + 500).then(function(){
iProgress(0.33, "Done sending!");
});
}
// disconnect is similar
Now, we can easily decide how our promises compose, for example:
function aggregateProgress(num){
var total = 0;
return function(progression,message){
total += progression;
console.log("Progressed ", ((total/num)*100).toFixed(2)+"%" );
console.log("Got message",message);
}
}
Which would let you do:
// bombard can accept iProgress itself if it needs to propagate it
function bombard() {
var notify = aggregateProgress(cmds.length+1);
return connect(notify)
.then(function () {
var cmds = [/*many commands in string*/];
return Q.all(cmds.map(function(command){ return send(command,notify); }));
});
}
Here is a complete and working fiddle to play with
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…