Angular RxJS将sync,async和forkJoin组合在一个主题流

时间:2018-03-15 09:42:00

标签: angular rxjs angular5 rxjs5

我有一个相当复杂的反应行为,我想用RxJS实现,但我还没有找到合适的解决方案。

Plnkr中可以找到的角度应用程序中,我有一系列同步,异步和并行异步执行。

  1. 首先,用户点击我的RxJS主题旁边的一个按钮 userClick$ = new Subject<void>();

    <button (click)="model.on = !model.on; userClick$.next()"> {{ model.on ? 'Stop' : 'Start' }} </button>

  2. 然后我使用getRandomNumber
  3. 提供一个随机数
  4. 然后我使用getExpNumber
  5. 计算该随机数的指数
  6. 最后,我需要并行运行getFloorgetCeil
  7. 我需要什么?

    • 能够在最后两次并行执行中使用forkJoin#4。
    • 能够在#3上表达#3对#2和#4的依赖关系:
      • getExpNumber取决于getRandomNumber并在其后运行
      • getFloor与getCeil并行运行,两者都依赖于getExpNumber。
    • 能够在我的每个flatMap中使用流的返回值,目前我只获取最后一个值(我需要使用{{1}向用户显示随机值(第一个flatMap) }和ngFor管道。

    Depencency:我可以通过检查每个async中当前可观察值的类型来实现这一点,但我认为必须有更好的方法。

    完整代码:

    flatMap

2 个答案:

答案 0 :(得分:1)

对我来说,创建可观察对象的方式很奇怪(我将使用&#34;&#34;)并且我会收到数字,而不是数组,所以代码就像

@Component({
  selector: 'my-app',
  template: `
    <button (click)="model.on = !model.on; userClick$.next()">{{ model.on ? 'Stop' : 'Start' }}</button>
    <h1>Numbers stream</h1>
    <h2 *ngFor="let numberValue of (numbers$ |async)">{{numberValue}}</h2>
    <label>{{ model.log }}</label>
  `,
})
export class HomeComponent {
  model = {
    on: false,
    log: ''
  }
  userClick$ = new Subject<void>();
  numbers$: Observable<number[]> = this.userClick$
    .switchMap(() => {
      return this.getRandomNumber().switchMap((num: number) => {
        this.model.log += num;
        return this.getExpNumber(num).switchMap((num2: number) => {
          this.model.log += num2;
          return forkJoin(this.getFloor(num2), this.getCeil(num2))
        })
      })
    })


  getRandomNumber(): Observable<number> {
    this.model.log += ' getRandomNumber';
    return of((Math.random() * 10) + 1);
  }
  getExpNumber(n: number): Observable<number> {
    this.model.log += ' getExpNumber';
    return of(Math.exp(n));
  }
  getFloor(n: number): Observable<number> {
    this.model.log += ' getFloor';
    return of((Math.floor(n)));
  }

  getCeil(n: number): Observable<number> {
    this.model.log += ' getCeil';
    return of(Math.ceil(n));
  }
}
  1. 不使用&#34;做&#34;,做是为了检查回复
  2. 如果我像你一样制作可观察物,叉子就不会工作(调用功能,但我不能订阅它们)

答案 1 :(得分:1)

如果您只想getRandomNumber,则只能订阅getRandomNumber。

this.getRandomNumber().subscribe((value:number)=>{console.log(value)}) 

注意:我们写的时候

<div *ngFor="let value of ($numbers |async)>{{value}}</div>

是“喜欢”

//in .html
<div *ngFor="let value of numberList>{{value}}</div>
//in .ts
numberList:number[]
subscription:Subscription;

ngOnInit()
{
  this.subscription=$numbers.subscribe(values:number[]=>{
      this.numberList=values;
      this.subscription.unsubscribe()
  }
}