我有以下代码:
obs.pipe(
switchMap((val) => {
// some logic...
return iif(() => condition, someObservable())
})
);
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么不能通过简单的而不是实现这if一点iif?
if (condition) {
return someObservable();
}
Run Code Online (Sandbox Code Playgroud)
看看下面的实现iif:
export function iif<T = never, F = never>(
condition: () => boolean,
trueResult: SubscribableOrPromise<T> = EMPTY,
falseResult: SubscribableOrPromise<F> = EMPTY
): Observable<T|F> {
return defer(() => condition() ? trueResult : falseResult);
}
Run Code Online (Sandbox Code Playgroud)
iif用于defer仅在订阅(外部)Observable 时调用条件函数并选择一个(内部)Observable。这在内部使用时并没有什么区别,switchMap因为 switchMap 内部的代码在每次发出时都会执行,但当您用于iif创建 Observable 并稍后订阅它时,会导致不同的行为。
const { iif, of, concat } = rxjs;
let subscribeToFirst;
const obs$ = concat(
iif(() => subscribeToFirst, of('iif-first'), of('iif-second')), // use 'iif'
subscribeToFirst ? of('if-first (never logged)') : of('if-second') // use 'if'
);
// Change at runtime which Observable will be subscribed
// works for 'iif' but not for 'if'
console.log('----- subscribe to first -----');
subscribeToFirst = true;
obs$.subscribe(value => console.log(value));
console.log('----- subscribe to second -----');
subscribeToFirst = false;
obs$.subscribe(value => console.log(value));Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>Run Code Online (Sandbox Code Playgroud)
除此之外,文档还说它的iif存在是为了方便:
实际上 iif 可以很容易地用 defer 实现,并且只是为了方便和可读性的原因而存在。