RpJS / Angular结合了可点运算符

时间:2019-11-11 08:58:17

标签: angular typescript rxjs rxjs-pipeable-operators

是否有可能(我无法找到任何全面的信息)在一个函数中组合多个可点运算符,因此我可以通过管道将其组合并以其他方法重复使用?

这是东西:

public ngOnInit(): void {
      this.route.url
            .pipe(
                switchMap( (ids: UrlSegment[]) => /* http call */),
                tap(result => /* setting a variable within a service */),
                tap(result => /* some more manipulating and logic */),
                map(result => /* setting a _this_ variable */)
            )
            .subscribe( () => {
                /* some other async tasks, which depend on _this_ variables */
                this.cdr.detectChanges();
            });
      }

如何提取pipe()中的所有内容,以便可以从不同的方法调用同一操作符链,而该方法需要执行相同的http调用以及随后的逻辑和操作?

我想要实现的是:

 this.route.url
   .pipe(
       this.combinedPipableMethod(url: UrlSegment[])
   )
   .subscribe()

3 个答案:

答案 0 :(得分:3)

您可以提取一种方法:

getData(ids: UrlSegment[]) {
   return this.http.get(/* url construction logic */)
      .pipe(
         tap(result => /* setting a variable within a service */),
         tap(result => /* some more manipulating and logic */),
         map(result => /* setting a _this_ variable */)
      );
}

然后switchMap

public ngOnInit(): void {
   this.route.url
      .pipe(
          switchMap(this.getData),
       )
       .subscribe( () => {
          /* some other async tasks, which depend on _this_ variables */
          this.cdr.detectChanges();
       });
}

否则,您可以创建一个自定义运算符,但是这样做似乎有点过分:

const combinedPipableMethod = () => {
  return source => defer(() => {
    return source.pipe(
       switchMap((ids: UrlSegment[]) => /* http call */),
       tap(result => /* setting a variable within a service */),
       tap(result => /* some more manipulating and logic */),
       map(result => /* setting a _this_ variable */)
    )
  })
}
public ngOnInit(): void {
   this.route.url
      .pipe(
          combinedPipableMethod(),
       )
       .subscribe( () => {
          /* some other async tasks, which depend on _this_ variables */
          this.cdr.detectChanges();
       });
}

答案 1 :(得分:1)

您可以使用rxjs pipe(请注意,它是一个独立的函数,不是Observable的方法),可以将一系列运算符组合成一个可重用的运算符。

import { pipe } from "rxjs";
 const customPipable = pipe(
     switchMap( (ids: UrlSegment[]) => /* http call */),
     tap(result => /* setting a variable within a service */),
     tap(result => /* some more manipulating and logic */),
     map(result => /* setting a _this_ variable */)
 )
  this.route.url
  .pipe(customPipable)
  .subscribe()

Here is an article about it

答案 2 :(得分:0)

您可以将链存储在Subject中,然后只需在主题上调用next()即可强制管道运行

//Subject for storing pipeline
loadDataSubject = new Subject();

ngOnInit() {
  loadDataPipe(this.loadDataSubject).subscribe(
     /* some other async tasks, which depend on _this_ variables */
     this.cdr.detectChanges();
  )
}

loadDataPipe(source) {
  return source.pipe(
       switchMap( (ids: UrlSegment[]) => /* http call */),
       tap(result => /* setting a variable within a service */),
       tap(result => /* some more manipulating and logic */),
       map(result => /* setting a _this_ variable */)
  )
}

现在随时可以使用next()在任何地方调用管道再次运行:

 ....
 this.loadDataSubject.next();
 ....