可观察确定订户功能是否已完成

时间:2017-05-01 16:32:35

标签: javascript typescript promise rxjs observable

确定订阅者是否已完成执行或更好地返回某些内容并将其上传的最佳方法是什么?例如:

    this._subscriptions.push(this._client
        .getCommandStream(this._command) // Returns an IObservable from a Subject stream
        .subscribe(msg => {
            // Do some processing maybe some promise stuff
            http.request(url).then(
                // some more stuff
            );
        });

确定订阅已完成的最佳方法是什么。我按如下方式实现了它:

    this._subscriptions.push(this._client
        .getCommandStream(this._command)
        .subscribe(msg => {
            // Do some processing maybe some promise stuff
            http.request(url).then(re => {
                // some more stuff
                msg.done()
            }).catch(err => msg.done(err));
        });

即。向传入的对象添加了done方法以确定是否已完成。问题是我必须在每个承诺或捕获块中调用done并发现有点过于详尽。是否有更清洁,更自动化的方式?

我认为我给出的例子不够好。此实现使用RX构建内部消息传递总线。 get命令流实际上返回一个只读通道(作为Observable)来获取命令并处理它们。现在处理可以是http请求,后跟许多其他内容或只是if语句。

this._client
.getCommandStream(this._command) // Returns an IObservable from a Subject stream
  .subscribe(msg => {
      // Do some processing maybe some promise stuff
      http.request(url).then({
          // some more stuff

          }).then({
            // Here I wanna do some file io
            if(x) {
                file.read('path', (content) => {
                    msg.reply(content);
                    msg.done();
                });
            } else {
            // Or maybe not do a file io or maybe even do some image processing
                msg.reply("pong");
                msg.done()
            }
            });
      });

我觉得这是O​​bservable模式的一个很好的用法,因为这正是一系列命令进来,这个逻辑想要对它们采取行动。问题是在整个地方都要注意msg.done()。我想知道限制该调用的最佳方法是什么,并知道整个事情何时完成。另一个选择是将它全部包含在Promise中,但是再次将resolvemsg.done()之间的差异包含在内?

2 个答案:

答案 0 :(得分:1)

实际上,不推荐在subscribe()内部发出另一个异步请求,因为它只会使事情变得更复杂,并且以这种方式使用Rx并不能帮助您更好地理解代码。

由于您需要向返回PRomise的远程服务发出请求,因此您可以将其合并到链中:

this._subscriptions.push(this._client
    .getCommandStream(this._command)
    .concatMap(msg  => http.request(url))
    .subscribe(...)

subscribe的第3个参数是在源Observable完成时调用的回调。

您还可以在处理链时添加自己的拆卸逻辑。在complete调用subscribe(...)回调之后,这称为

const subscription = this._subscriptions.push(this._client
    ...
    .subscribe(...)

subscription.add(() => doWhatever())

顺便说一句,这相当于使用finally()运算符。

答案 1 :(得分:0)

根据RxJs订阅方法文档,最后Argument已完成函数

var source = Rx.Observable.range(0, 3)

var subscription = source.subscribe(
  function (x) {
    console.log('Next: %s', x);
  },
  function (err) {
    console.log('Error: %s', err);
  },
  function () {
    console.log('Completed');
  });

请参阅this文档

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/subscribe.md