如果使用返回不同observable的函数,如:
const load = () => {
if (!activated) {
return of(null);
} else {
return of(123);
}
}
如果您使用combineLatest
,那么即使您将activated
更改为true,它也始终是当时返回的值。
combineLatest(load(), b)
.pipe(map(([num, str]) => `${num}:${str}`))
.subscribe(data => log(`result: ${data}`))
b.next('a');
activated = true;
b.next('b'); // should log "123:b", but it doesn't
您可以在此处查看完整示例:https://stackblitz.com/edit/combinelatest-dynamically
任何可以获得更新版本的解决方案?
ps:我没有一个订阅,因为它是localStorage的中间件
答案 0 :(得分:3)
您只需要activated
可观察,并将其提供给load()
。以下内容是根据您的stackblitz修改的。
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { combineLatest } from 'rxjs/observable/combineLatest';
import {merge} from "rxjs/observable/merge";
import { of } from 'rxjs/observable/of';
import { defer } from 'rxjs/observable/defer';
import { map, switchMap } from 'rxjs/operators';
const activated = new BehaviorSubject<boolean>(false);
const b = new ReplaySubject<any>();
const load = (activated) => {
if (!activated) {
return of(null);
} else {
return of(123);
}
}
combineLatest(defer(() => activated.pipe(switchMap(x => load(x)))), b)
.pipe(map(([num, str]) => `${num}:${str}`))
.subscribe(data => log(`result: ${data}`))
b.next('a');
activated.next(true);
b.next('b'); // should log "123:b", but it doesn't
// Utils
function log(v) {
document.body.querySelector('pre').appendChild(document.createElement('div')).textContent = v;
}