嗯,问题本身很难简单描述,所以这里有一个 live example展示。看来我误解了 Rx.js 的工作原理,否则这里的功能来自一个错误。
我尝试做的是一个简单的响应式(Reactive)渲染设置,您在屏幕上看到的内容以及发生的事件都以可观察到的方式进行描述。问题在于,由于某种难以察觉的原因,当以一种方式编写代码时,事件会完全被丢弃,但理论上应该是等效的代码却可以正常工作。
那么,让我们从上面示例代码中的第一种情况开始:
var dom = makeBox('one');
var clicks = Rx.Observable.fromEvent(dom, 'click');
如果你创建一个 DOM 片段,那么你可以简单地使用 fromEvent 来获取它发出的任何事件的 Observable。到目前为止,一切都很好。您可以单击此框并查看写入日志的一堆行。
现在,下一步是使 DOM 具有响应性,以表达它如何随时间变化。
var domStream = Rx.Observable.return(makeBox('two'));
var clicks = domStream.flatMapLatest(function(dom) {
return Rx.Observable.fromEvent(dom, 'click');
});
这将使它成为一个 Observable,在这里使用 return 来生成最简单的常量情况。您感兴趣的事件将是由最新版本的 dom 发出的事件,而这正是 flatMapLatest 运算符所做的事情。这个变体仍然有效。
最终,目标是根据某些应用程序状态生成当前 DOM 状态。也就是说,将其从一个 Observable 映射到另一个 Observable。现在让我们使用最简单的版本,使用单个常量值作为状态,然后将其映射到我们之前使用的相同固定输出:
var updates = Rx.Observable.return(1);
var domStream = updates.map(function (update) {
return makeBox('three');
});
var clicks = domStream.flatMapLatest(function(dom) {
return Rx.Observable.fromEvent(dom, 'click');
});
这应该与以前的版本没有任何不同。但是,无论您做什么,这都不会输出任何事件。
这里到底发生了什么?我是否误解了 Rx 的一些基本概念,或者什么?我遇到了一些关于热 Observable 和冷 Observable 的问题,但这在这个最小的情况下似乎无关。所以,我有点没有主意了。谁能帮我解答一下吗?
最佳答案
很抱歉告诉您,这是一个热与冷
问题。
这是一个微妙的问题,但两者之间的区别
Rx.Observable.return(makeBox('two'))
和
Rx.Observable.return(1).map(function() {return makeBox('三'); })
是不是第一个每次订阅都会返回一个常量,即
您最初创建的一个盒子。每次订阅 Observable
时,第二个都会返回一个 new 框,这会导致问题,因为您实际上订阅了 domStream
变量两次,您正在创建 Box 3 的两个实例,一个具有事件处理程序但未显示,另一个没有但显示。
解决方法是您需要使用方法 2或者您需要使用以下方法将第三种方法转换为热流:
domStream.replay(1).refCount()
或者通过使用
domStream.publish()
然后在所有订阅完成后:
domStream.connect()
关于javascript - 来自Event + flatMapLatest的Rx.js坏了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32168335/