How to call Q promise notify within the promise chain

前端 未结 1 901
闹比i
闹比i 2020-12-21 04:14

I need helps on notify() within the promise chain.

I have 3 promise base functions connect(), send(cmd), disconnect()

相关标签:
1条回答
  • 2020-12-21 04:37

    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

    0 讨论(0)
提交回复
热议问题