如何使用combineLatest与动态返回的函数Observable?

时间:2018-05-03 14:44:13

标签: rxjs

如果使用返回不同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的中间件

1 个答案:

答案 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;
}