如何在承诺链中调用Q promise通知

Mon*_*Wan 4 javascript promise q

我需要notify()在承诺链中提供帮助.

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

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() })
}
Run Code Online (Sandbox Code Playgroud)

运行这样的功能

bombard.then(onResolve, onReject, function (obj) {
 console.log(ob);
});
Run Code Online (Sandbox Code Playgroud)

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

虽然我相信这是由于这些通知没有带传播到外界的承诺,我对如何传播的,承诺链子Q或包装的通知,不知道:connect,send,disconnect在一个延迟对象.

谢谢

Ben*_*aum 12

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

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

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

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

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
Run Code Online (Sandbox Code Playgroud)

现在,我们可以轻松决定我们的承诺如何构成,例如:

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);
     }
}
Run Code Online (Sandbox Code Playgroud)

哪个会让你这样做:

// 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); }));
  });
}
Run Code Online (Sandbox Code Playgroud)

这是一个完整而有效的小提琴