switchMapTo 源可观察发射
switchMapTo upon source observable emission
switchMap
和 switchMapTo
的区别在于 switchMap
将每个源发射转换为可观察到的发射,而 switchMapTo
忽略发射值并将每个发射转换为在 流创建 期间建立的 Observable。
此处的经验法则是当您的内部流依赖于源流值时使用 switchMap
,否则使用 switchMapTo
。
但是如果我不关心发射值但我关心发射时间怎么办?
这意味着我希望在源 Observable 发射时评估内部 Observable。
这里显而易见的是使用 switchMap(() => Observable)
,但由于我之前提到的经验法则,它感觉不对。
示例 switchMapTo
(不好):
const predefinedKey = 'key';
//This need to be initialized
const obj = {};
function getObservable(key){
return Rx.Observable.of(obj[key]);
}
//This is initialization stream
const initialize = new Rx.ReplaySubject();
initialize.next(1);
const onInit = initialize.do(val => obj[predefinedKey] = val);
//Would like to access the object only after initialization
const result = onInit.switchMapTo(getObservable(predefinedKey));
//Expect to see 1 in output but see 'undefined' because switchMapTo evaluated before the object is initialized
result.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
示例switchMap
(好):
const predefinedKey = 'key';
//This need to be initialized
const obj = {};
function getObservable(key){
return Rx.Observable.of(obj[key]);
}
//This is initialization stream
const initialize = new Rx.ReplaySubject();
initialize.next(1);
const onInit = initialize.do(val => obj[predefinedKey] = val);
//Would like to access the object only after initialization
const result = onInit.switchMap(() => getObservable(predefinedKey));
//Expect to see 1 in output
result.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
这些例子非常虚假,但它们很好地描述了情况。
这里正确的方法是什么?我可以使用任何其他 Observable 函数来延迟执行吗?
根据您的示例,您可以将 switchMapTo
与 Observable.defer
结合使用:
const predefinedKey = 'key';
const obj = {};
function getObservable(key){
return Rx.Observable.defer(() => Rx.Observable.of(obj[key]));
}
const initialize = new Rx.ReplaySubject();
initialize.next(1);
const onInit = initialize.do(val => obj[predefinedKey] = val);
const result = onInit.switchMapTo(getObservable(predefinedKey));
result.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
除了在 getObservable
中延迟,您还可以在 switchMapTo
调用中延迟:
const result = onInit.switchMapTo(Rx.Observable.defer(() => getObservable(predefinedKey)));
这要视情况而定。也就是说,我也不认为使用 switchMap
有什么问题,就个人而言,我可能会这样做而不是推迟(这在其他情况下很有用)。
switchMap
和 switchMapTo
的区别在于 switchMap
将每个源发射转换为可观察到的发射,而 switchMapTo
忽略发射值并将每个发射转换为在 流创建 期间建立的 Observable。
此处的经验法则是当您的内部流依赖于源流值时使用 switchMap
,否则使用 switchMapTo
。
但是如果我不关心发射值但我关心发射时间怎么办?
这意味着我希望在源 Observable 发射时评估内部 Observable。
这里显而易见的是使用 switchMap(() => Observable)
,但由于我之前提到的经验法则,它感觉不对。
示例 switchMapTo
(不好):
const predefinedKey = 'key';
//This need to be initialized
const obj = {};
function getObservable(key){
return Rx.Observable.of(obj[key]);
}
//This is initialization stream
const initialize = new Rx.ReplaySubject();
initialize.next(1);
const onInit = initialize.do(val => obj[predefinedKey] = val);
//Would like to access the object only after initialization
const result = onInit.switchMapTo(getObservable(predefinedKey));
//Expect to see 1 in output but see 'undefined' because switchMapTo evaluated before the object is initialized
result.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
示例switchMap
(好):
const predefinedKey = 'key';
//This need to be initialized
const obj = {};
function getObservable(key){
return Rx.Observable.of(obj[key]);
}
//This is initialization stream
const initialize = new Rx.ReplaySubject();
initialize.next(1);
const onInit = initialize.do(val => obj[predefinedKey] = val);
//Would like to access the object only after initialization
const result = onInit.switchMap(() => getObservable(predefinedKey));
//Expect to see 1 in output
result.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
这些例子非常虚假,但它们很好地描述了情况。
这里正确的方法是什么?我可以使用任何其他 Observable 函数来延迟执行吗?
根据您的示例,您可以将 switchMapTo
与 Observable.defer
结合使用:
const predefinedKey = 'key';
const obj = {};
function getObservable(key){
return Rx.Observable.defer(() => Rx.Observable.of(obj[key]));
}
const initialize = new Rx.ReplaySubject();
initialize.next(1);
const onInit = initialize.do(val => obj[predefinedKey] = val);
const result = onInit.switchMapTo(getObservable(predefinedKey));
result.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
除了在 getObservable
中延迟,您还可以在 switchMapTo
调用中延迟:
const result = onInit.switchMapTo(Rx.Observable.defer(() => getObservable(predefinedKey)));
这要视情况而定。也就是说,我也不认为使用 switchMap
有什么问题,就个人而言,我可能会这样做而不是推迟(这在其他情况下很有用)。