تايب سكريبت - مشغلات قابلة للتركيب مع RxJS/أنغولار


هل من الممكن (لا أستطيع أن أجد أي شيء شامل حول هذا) دمج عدة مشغلين يمكن توصيلهما بالأنابيب في دالة واحدة، حتى أتمكن من توصيلها بالأنابيب وإعادة استخدامها في طريقة مختلفة أيضًا؟

إليك الأمر:

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

الإجابة رقم 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()

إليك مقالًا عن ذلك

الإجابة رقم 2

يمكنك استخراج طريقة:

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