我有以下代码:
obs.pipe(
switchMap((val) => {
// some logic...
return iif(() => condition, someObservable())
})
);
我只是想知道为什么不能通过简单的if
而不是iif
来实现?
if (condition) {
return someObservable();
}
答案 0 :(得分:1)
看看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);
}
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));
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
除此之外,文档还指出iif
是为了方便起见:
实际上,iif可以很容易地延迟实现,并且仅出于方便和易读性的原因而存在。
答案 1 :(得分:0)
如评论中所述:
在第一种情况下,如果条件为false,则结果流将立即完成。在第二种情况下,如果条件为假,则看来您没有返回任何流。为了进行比较,第二个示例将需要一个else并返回EMPTY。 iif的文档在这里:rxjs.dev/api/index/function/iif
使用true和false条件,这些语句将具有可比性:
getUser() {
const url = `${this.userUrl}/${this.currentUserId}`;
this.todosForUser$ = this.http.get<User[]>(url).pipe(
switchMap(user => {
return iif(
() => this.todos,
this.http.get<ToDo[]>(`${this.todoUrl}?userId=${this.currentUserId}`),
this.http.get<Post[]>(`${this.postUrl}?userId=${this.currentUserId}`)
);
})
);
}
和
getUser() {
const url = `${this.userUrl}/${this.currentUserId}`;
this.todosForUser$ = this.http.get<User[]>(url).pipe(
switchMap(user => {
if (this.todos) {
return this.http.get<ToDo[]>(`${this.todoUrl}?userId=${this.currentUserId}`);
} else {
return this.http.get<Post[]>(`${this.postUrl}?userId=${this.currentUserId}`);
}
})
);
}
您可以在此处找到堆叠闪电战:https://stackblitz.com/edit/angular-todos-deborahk-iif
因此,您和您的团队认为这是最容易阅读的。