最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to call Q promise notify within the promise chain - Stack Overflow

programmeradmin1浏览0评论

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

I have 3 promise base functions connect(), send(cmd), disconnect(). Now I would like to write another function to wrap those call in following manner with progress notification.

function bombard() {
 return connect()
  .then(function () {
    var cmds = [/*many mands in string*/];
    var promises = _.map(cmds, function (cmd) {
     var deferred = Q.defer();
     deferred.notify(cmd);
     send(cmd).then(function (result) {
      deferred.resovle(result);
     });
     return deferred.promise;
    });
    return Q.all(promises);
  })
 .finally(function () { return disconnect() })
}

Run the function like that

bombard.then(onResolve, onReject, function (obj) {
 console.log(ob);
});

I supposed I will get notification for every mand I have sent. However, it does not work as I expected. I get nothing actually.

Although I believe this is due to those notifications havn't propagated to outside promise, I have no idea on how to propagated those notifications on Q or wrapping that promise chain: connect, send, disconnect in a one deferred object.

Thanks

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

I have 3 promise base functions connect(), send(cmd), disconnect(). Now I would like to write another function to wrap those call in following manner with progress notification.

function bombard() {
 return connect()
  .then(function () {
    var cmds = [/*many mands in string*/];
    var promises = _.map(cmds, function (cmd) {
     var deferred = Q.defer();
     deferred.notify(cmd);
     send(cmd).then(function (result) {
      deferred.resovle(result);
     });
     return deferred.promise;
    });
    return Q.all(promises);
  })
 .finally(function () { return disconnect() })
}

Run the function like that

bombard.then(onResolve, onReject, function (obj) {
 console.log(ob);
});

I supposed I will get notification for every mand I have sent. However, it does not work as I expected. I get nothing actually.

Although I believe this is due to those notifications havn't propagated to outside promise, I have no idea on how to propagated those notifications on Q or wrapping that promise chain: connect, send, disconnect in a one deferred object.

Thanks

Share Improve this question asked May 26, 2014 at 8:03 Mond WanMond Wan 1,9122 gold badges17 silver badges21 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 11

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 pose 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 pose, 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 mands in string*/];
    return Q.all(cmds.map(function(mand){ return send(mand,notify); }));
  });
}

Here is a plete and working fiddle to play with

发布评论

评论列表(0)

  1. 暂无评论