Javascript Rx行为主体&x2B;扫描将以前的事件推送到新订户?
我想有一个流,我可以推动减速器功能。每次推送reducer函数时,都应将状态对象传递给reducer,reducer应返回修改后的状态值,更新后的状态应推送给订阅服务器。我希望我的代码可以解释:Javascript Rx行为主体&x2B;扫描将以前的事件推送到新订户?,javascript,rxjs,Javascript,Rxjs,我想有一个流,我可以推动减速器功能。每次推送reducer函数时,都应将状态对象传递给reducer,reducer应返回修改后的状态值,更新后的状态应推送给订阅服务器。我希望我的代码可以解释: import Rx from 'rx'; import { Map } from 'immutable'; let initialState = Map({ counter: 0 }); export let upstream = new Rx.BehaviorSubject(Rx.helpers.
import Rx from 'rx';
import { Map } from 'immutable';
let initialState = Map({ counter: 0 });
export let upstream = new Rx.BehaviorSubject(Rx.helpers.identity);
export let downstream = upstream.scan((state, reducer) => {
return reducer(state);
}, initialState);
let increment = state => {
return state.update('counter', counter => counter + 1);
};
upstream.onNext(increment);
downstream.subscribe(state => {
console.log('subscriptionA', state.get('counter'));
});
upstream.onNext(increment);
setTimeout(() => {
downstream.subscribe(state => {
console.log('subscriptionB', state.get('counter'));
});
}, 3000);
以下是我看到的输出:
subscriptionA 1
subscriptionA 2
subscriptionB 1
当我希望看到:
subscriptionA 1
subscriptionA 2
subscriptionB 2
显然,我在这里遗漏了一些基本的东西。似乎<代码>行为主题< /代码>应该保留新用户的最新值,这将使我认为当<代码>订阅pB/<代码>订阅<代码>下游< /代码>时,它将得到最新的缩减值,但它看起来像是<代码>。
这里发生了什么,我如何完成我想要完成的事情?谢谢 我有一个解决方案,它似乎给了我想要的结果。如果其他人能证明这是一个合适的解决方案,我将不胜感激
import Rx from 'rx';
import { Map } from 'immutable';
let initialState = Map({ counter: 0 });
export let upstream = new Rx.Subject();
let downstreamSource = upstream.scan((state, reducer) => {
return reducer(state);
}, initialState);
export let downstream = new Rx.BehaviorSubject(initialState);
downstreamSource.subscribe(downstream);
let increment = state => {
return state.update('counter', counter => counter + 1);
};
upstream.onNext(increment);
downstream.subscribe(state => {
console.log('subscriptionA', state.get('counter'));
});
upstream.onNext(increment);
setTimeout(() => {
downstream.subscribe(state => {
console.log('subscriptionB', state.get('counter'));
});
}, 3000);
如果你更换了,你能试着看看是否一切都符合你的期望吗
export let downstream = upstream.scan((state, reducer) => {
return reducer(state);
}, initialState);
借
请点击此处:
如果是这样的话,你是另一个热与冷的受害者,这是Rx.Observable
,或者更准确地说是观察对象的惰性实例化
简而言之(不是很短),每次你订阅一个时发生的事情是,一个观察链是通过向操作符链的上游移动而创建的。每个操作符订阅它的源,并返回另一个可观察到的源。在您的情况下,当您订阅scan
时,scan
订阅上游
,这是最后一个<代码>上游
作为主题,订阅时只注册订户。其他源会做其他的事情(比如在DOM节点上注册侦听器,或者套接字,等等)
这里的要点是,每次订阅
扫描
,您都会重新开始,即使用初始状态
。如果要使用从第一次订阅到扫描
的值,必须使用共享
运算符。在第一次订阅共享
时,它会将您的订阅请求传递到扫描
。在第二次和后续的扫描中,它将不会对其进行注册,并将来自首次订阅的扫描的所有值转发给相关的观察者。感谢您的回复。如果我添加share()
,那么结果是:subscriptiona1
subscriptiona2
我没有通过subscriptionB获得任何事件。我认为你的描述有些道理,而且很有帮助。没错,因为共享
你不再触及行为主题。。。但是,如果您在下一个勾选中发送了其他内容,并使用upstream.onNext
,您应该会看到它,尽管这并不能解决您的问题。然后,我能想到的是将你放入的shareReplay(1)
中的share
替换掉。可惜没有jsfiddle
我会在我这边玩它。如果这样做有效,那么你就不需要更多的行为主题了。shareReplay(1)
似乎可以做到这一点。参见这里的jsfiddle。快速单击增量按钮四次,然后等待超时过期,您应该会看到具有正确值的订阅B。正如您所见,您不再需要行为主题,重播将取代大部分功能。您是对的。这很有启发性,也很有道理。感谢您,也感谢您投入工作来制作JSFIDLE!
export let downstream = upstream.scan((state, reducer) => {
return reducer(state);
}, initialState).shareReplay(1);