typescript - Operator pipable gabungan dengan RxJS/Angular


Adakah mungkin (saya tidak dapat menemui apa-apa yang menyeluruh mengenai ini) untuk menggabungkan pelbagai operator yang boleh dipipakan dalam satu fungsi, supaya saya boleh memipkannya dan menggunakan semula dalam kaedah lain juga?

Ini adalah perkara ini:

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();
            });
      }

Bagaimana saya mengekstrak segala-galanya dalam pipe() supaya saya boleh memanggil rantaian operator yang sama dari kaedah lain, yang akan perlu melakukan panggilan http yang sama dan logik serta manipulasi seterusnya?

Apa yang saya cuba capai adalah:

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

Jawapan #1

Anda boleh menggunakan fungsi rxjs pipe (Perhatikan, ia adalah fungsi berdiri sendiri, bukan kaedah bagi Observable) untuk menggabungkan satu urutan operator menjadi satu operator yang boleh digunakan semula.

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()

Berikut adalah sebuah artikel mengenainya

Jawapan #2

Anda boleh mengekstrak satu kaedah:

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 */)
      );
}

Dan kemudian switchMap kepadanya:

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

Jika tidak, anda boleh membuat operator tersuai tetapi ia nampak berlebihan untuk tujuan ini:

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();
       });
}