javascript - 如何在promise链中调用Q promise notify

标签 javascript promise q

我需要有关 promise 链中 notify() 的帮助。

我有 3 个 promise 基函数 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() })
}

像那样运行函数

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

我想我会收到我发送的每条命令的通知。但是,它并不像我预期的那样工作。我实际上什么也得不到。

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

谢谢

最佳答案

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

很好!您已经发现了通知 API 的问题,以及为什么它在 v2 分支的 Q 中被删除,在 Bluebird 等较新的库中被弃用,并且从未包含在 ECMAScript 6 中。这实际上归结为 promise 不是事件发射器这一事实.

通知 API 不能很好地组合或聚合。事实上,一开始就 promise 通知并没有多大意义。

相反,我建议甚至使用进度通知,有点像 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

现在,我们可以很容易地决定我们的 promise 如何组成,例如:

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

Here is a complete and working fiddle to play with

关于javascript - 如何在promise链中调用Q promise notify,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23865481/

相关文章:

javascript - react 中的 Xlsx sheetname 长度超过 31 个字符

javascript - 使用 Mongoose 和 NodeJS 在 MapReduce 中添加更多字段

javascript - 警告 : Can't perform a React state update on an unmounted component. 使用Effect清理函数

javascript - promise 解决后返回不工作

javascript - Q.js - 如何访问缓存的元素

angularjs - 类型错误 : Cannot read property 'then' of undefined angularjs-grunt test

javascript - 如何反复使用 onclick() & if 语句更改图像?

node.js - 如何在 Promisify 请求模块后正确使用 putAsync

node.js - 在 Q 中记录所有拒绝的 promise

javascript - 发送整个对象只是为了更新状态?