RXJS:根据可观察到的价值散发额外的价值

时间:2018-08-23 15:45:51

标签: typescript rxjs rxjs6

我是RxJs 6.0(或任何RxJs版本)的新手,尽管我看到它的功能强大,但一些简单的概念使我无所适从。

我遇到一种情况,我想根据源流向输出流中传递一个额外的值,但是对于我一生来说,我不知道该怎么做。我确实需要一个startsWith运算符,该运算符可以采用方法而不是静态值,然后可以实现这一点。这是设置场景的一些愚蠢的代码。

import { startWith, scan, tap, mergeMap, map, concat } from 'rxjs/operators';

interface IData {
  data: number;
  emitExtraVal: boolean;
}

class obsData implements IData {
  constructor(data: number) {
    this.data = data;
    this.emitExtraVal = false;
  }
  public data: number;
  public emitExtraVal: boolean;

}

class extraData implements IData {
  constructor(data: number) {
    this.data = data;
    this.emitExtraVal = true;
  }

  public data: number;
  public emitExtraVal: boolean;
}
const sourceOne = of(new obsData(1),new obsData(2),new obsData(3));
/*const finalSource = sourceOne.pipe(
  map((sData) => <IData>new extraData(sData.data)),
  map((sData) => sData)
);*/
const finalSource = sourceOne.pipe(
  mergeMap((sData) => concat(of(<IData>new extraData(sData.data), of(sData))))
);
const subscribe = finalSource.subscribe(val => console.log('Data:' + val.emitExtraVal));

我想做的是输出一个ExtraData实例,该实例带有obsData中的数字,后跟我刚从源中获取的obsData。这不是我要尝试的确切场景,但它演示了我正在尝试做的核心工作,即创建一个额外的输出,然后再创建另一个输出,这两个输出均依赖于单个源输入。

此问题的更新示例基于注释,但是由于语法不正确,该示例无法运行

这会产生以下错误:

您提供了'function(source){return source.lift.call(concat_1.concat.apply(void 0,[source] .concat(observables))); }'预计会出现流。您可以提供一个Observable,Promise,Array或Iterable。

---更新--- 感谢您的回答,这是行之有效的最终答案。我遇到的主要问题是可以从rxjs / operators或rxjs导入concat。如果在pipe命令中使用它,则必须从rxjs导入它。

// RxJS v6+
import { of, fromEvent, combineLatest, concat } from 'rxjs';
import { startWith, scan, tap, mergeMap, map } from 'rxjs/operators';

interface IData {
  data: number;
  emitExtraVal: boolean;
}

class obsData implements IData {
  constructor(data: number) {
    this.data = data;
    this.emitExtraVal = false;
  }
  public data: number;
  public emitExtraVal: boolean;

}

class extraData implements IData {
  constructor(data: number) {
    this.data = data;
    this.emitExtraVal = true;
  }

  public data: number;
  public emitExtraVal: boolean;
}
const sourceOne = of(new obsData(1),new obsData(2),new obsData(3));

const finalSource = sourceOne.pipe(
  mergeMap((sData) => concat(of(<IData>new extraData(sData.data), <IData>sData)))
);
const subscribe = finalSource.subscribe(val => console.log('Data:' + val.emitExtraVal));

1 个答案:

答案 0 :(得分:0)

  

创建一个额外的输出,然后再创建另一个输出,这两个输出均依赖于单个源输入。

在我的示例中, dataItem 是“单个源输入”,它使用from运算符转换为Observable元素。之后,您可以使用flattening operators(如mergeMapconcatMap视需求而定)将所有这些Observable都“扁平化”为一个。参见示例:

const { Observable, of, from, concat } = rxjs; // = require("rxjs")
const { mergeMap } = rxjs.operators; // = require("rxjs/operators")

const complexAjaxCall = id => of(`${id}-from-ajax`);

const ids = [1, 2, 3];

from(ids).pipe(
  mergeMap(id => concat(
    complexAjaxCall(id),
    of(id)
  )),
).subscribe(e => console.log(e));
<script src="https://unpkg.com/rxjs@6.2.2/bundles/rxjs.umd.min.js"></script>