RxJS:手动触发 Observable 的正确方式

11

使用 RxJS 在 Angular 4.x 中,我看到有两种非常不同的模式可以从用户发起的操作流中生成 Observables。一个流是直接由用户点击“添加项目”按钮生成新对象的结果。另一个是由我正在使用的某些第三方代码发出的一系列事件。

我希望能够使用类似“combineLatest”的方法将这两个流组合起来生成单个的 Observable。

对于我的按钮,我遵循了以下模式:

const signal = Observable.create(
            (observer) => {
                this.additem= (item) => observer.next(item);
            }
        );

this.item$ = signal.map((item) => [item])
                            .scan((accumulator, value) => {
                                return accumulator.concat(value);
                            });

然而,我看到很多信息说我应该使用Subjects - 我正在尝试在我的事件回调中使用它,如下所示:

sort$ = new Subject();

sortChange(sort){
        sort$.next(sort);
}

然后我尝试像这样将它们组合起来:

combine$ = Observable.combineLatest(sort$, item$,
                  (sort, items) => {
                      return "something that does stuff with these";}
        );

我的问题是 - 生成“手动”流的首选模式是什么?可不可以/应该将Observables和Subjects混合在一起成为一个单一的Observable,就像我在这里尝试做的那样?


我认为这个问题的最佳信息来源是这个答案:https://dev59.com/kVkS5IYBdhLWcg3ww45d 即使你的问题不完全与这个重复,对我来说,它似乎是你需要做出选择的答案。 - Supamiu
如果你想要合并两个Observable,你可以使用merge操作符。 - alehn96
很抱歉,我已经看了你的代码两个小时了...但我还是无法理解这里this.item到底在做什么?你是如何调用那个函数的?从我所看到的,你可能正在尝试将你在按钮点击时创建的项目传递给可观察对象? - Samarth Saxena
1个回答

10
当然,你可以将Observable和Subject结合成一个流。
我认为问题在于,在您的使用情况下,哪种方式更有意义。根据您的描述,当实现像“添加项目”功能时,我更喜欢使用Subject而不是Observable.create。
这是因为每次订阅您的信号时,都会重新分配this.additem。Observable.create的回调会针对每个观察者调用。请注意,更正确地使用Observable.create应该像这样:
const signal = Observable.create((observer) => {
   this.additem = (item) => observer.next(item);
   return () => this.additem = null;
});

当您取消订阅此Observable时,返回的回调() => this.additem = null将被调用,那就是您应该处理所有清理工作的地方。
然而,如果您对signal进行两次订阅,则会两次覆盖this.additem,然后如果您选择取消其中一个观察者,则会使this.additem = null,这可能会导致意外行为。
因此,在这种情况下,更合理的做法是使用Subject。例如:
const subject = new Subject();
this.additem = (item) => subject.next(item);

如果您想看更多 Observable.create 的实际例子,例如,请查看此链接:Subscribe to a stream with RxJS and twitter-stream-api module 编辑:还请查看RxJS 5的首席开发人员所写的这些文章:

谢谢!这就是我在寻找的答案类型。像这样的陷阱在查看文档时对我来说并不明显,而且我知道选择一种方法胜过另一种方法肯定有原因,因为两种方法都似乎可以工作。 - Potatoes
@Potatoes 我添加了一些我认为非常有帮助的文章链接。 - martin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接