Javascript RxJS:如何不订阅初始值和/或未定义?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28314882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RxJS: How to not subscribe to initial value and/or undefined?
提问by Pipo
Being new to RxJS I often create a subject which holds values in the future, but is initially undefined. It can only be undefinedthe first time. I currently use a filterto skip undefinedvalues, but this is quite cumbersome as I do it everywhereas I need only once. (Maybe I do something wrong here?) Can I somehow subscribe to mySubjectonly after it got its first value via onNext?
作为 RxJS 的新手,我经常创建一个具有未来价值的主题,但最初是undefined. 这只能是undefined第一次。我目前使用 afilter来跳过undefined值,但这很麻烦,因为我在任何地方都这样做,因为我只需要一次。(也许我在这里做错了什么?)我可以mySubject在它通过 获得第一个值后以某种方式订阅onNext吗?
var mySubject = new Rx.BehaviorSubject(undefined);
mySubject.filter(function(value) {
return value !== undefined;
}).subscribe(function(value) {
// do something with the value
});
回答by Brandon
Use new Rx.ReplaySubject(1)instead of BehaviorSubject.
使用new Rx.ReplaySubject(1)代替BehaviorSubject。
回答by lwohlhart
回答by Billy
mySubject.pipe( skipWhile( v => !v ) );
mySubject.pipe( skipWhile( v => !v ) );
回答by danguilherme
For now I am using the filteroperator, but I don't know if it's a good solution:
现在我正在使用filteroperator,但我不知道这是否是一个好的解决方案:
var mySubject = new Rx.BehaviorSubject().filter(x => !!x);
mySubject.subscribe(value => { /* will receive value from below */);
mySubject.next('value');
mySubject.subscribe(value => { /* also receives the value */ });
回答by Mukundhan
Sometimes there will be a need for behaviourSubject, where the initial value does not matter and the current value is needed asynchronously while working inside a stream, Just in our case multiple chain promises are handled with user cancel while processing or during fetching the data from anywhere inside the stream.
有时需要behaviorSubject,其中初始值无关紧要,并且在流内部工作时异步需要当前值,就像在我们的情况下,在处理或从任何地方获取数据期间,用户取消处理多个链承诺溪流内。
This can be achieved using the following way.
这可以使用以下方式实现。
// for user related commands
this.commandSource = new BehaviorSubject(CONTINUE);
// filtering over initial value which is continue to make it as a different pipe
const stopPipe = commandSource.pipe(filter(val => val === STOP));
const fetchStream = Observable.fromPromise(this.fetchDetails);
merge(fetchStream, stopPipe).pipe(
take(1),
takeWhile(() => commandSource.value === CONTINUE),
concatMap((response) => {
// fetch Another response you can return promise directly in concatMap
// return array of response [1 ,2 ,3];
return this.fetchYetAnotherDetails;
}),
// we can add this to stop stream in multiple places while processing the response
takeWhile(() => commandSource.value === CONTINUE),
// triggers parallelly values from the concatMap that is 1, 2 , 3
mergeMap(() => // massage the response parallelly using )
finalize(() => thi
commandSource.complete())
).subscribe(res => {
// handle each response 1, 2, 3 mapped
}, () => {
// handle error
}, () => {
// handle complete of the stream
});
// when user, clicks cancel, this should stop the stream.
commandSource.next(STOP)
回答by Pat Niemeyer
I have found this frustrating in both RxJS and RxSwift. (Wanting a value subject combined with the ability to wait on the first value).
我在 RxJS 和 RxSwift 中都发现这令人沮丧。(想要一个价值主体与等待第一个价值的能力相结合)。
For JS I am currently just tucking away a filtered version in the subject, something like this:
对于 JS,我目前只是在主题中隐藏一个过滤版本,如下所示:
let mySubject = new Rx.BehaviorSubject();
mySubject.wait = mySubject.pipe(filter(v=>v!==undefined));
So the subject is still exposed for publishing but clients don't have to repeat the filter.
所以该主题仍然公开发布,但客户不必重复过滤器。
mySubject.wait.subscribe((v)=>{...});

