本文介绍了如何在承诺链中调用Q promise通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我需要在承诺链中的 notify()上提供帮助。

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

我有3个承诺基函数 connect() send(cmd) disconnect() 。现在我想编写另一个函数,以下面的方式用进度通知来包装这些调用。

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 commands 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() })
}

运行函数那个

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

我想我会收到我发送的每个命令的通知。但是,它没有像我预期的那样工作。我什么都没得到。

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

虽然我认为这是由于这些通知没有传播到外部承诺,我不知道如何在Q上传播这些通知或包装该承诺链:在一个延迟对象中 connect 发送 disconnect

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.

谢谢

推荐答案

我有一些好消息和一些坏消息。

I have some good news and some bad news.

非常好!您已经发现了通知API的问题以及它在v2分支中被删除的原因,在Bluebird这样的新库中被弃用,并且从未包含在ECMAScript 6中。它实际上归结为promises不是事件发射器。

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.

通知API不能很好地组合或聚合。事实上,承诺上的通知开始时并没有太大意义,。

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,.

相反,我建议使用进度通知,有点像C#中的IProgress 。我将使用 Q.delay()模拟所有操作以进行隔离,您的代码显然会进行真正的调用

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);
     }
}

您可以这样做:

// 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); }));
  });
}

这篇关于如何在承诺链中调用Q promise通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-07 02:54