Как передать параметры в упакованный '.pipe ()' logi c изнутри другого .pipe () - PullRequest
1 голос
/ 07 августа 2020

Мне нужно выполнить один и тот же logi c для разных сервисных вызовов (например: myService.getA() и myService.putA()). Logi c включает в себя другие служебные вызовы, поэтому я делаю эти вызовы из .pipe().

Мой текущий logi c выглядит следующим образом:

this.myService.getItemA()
    .pipe(
        filter(itemA => {
            if (itemA.property) {
                this.itemA = itemA;
                return true;
            } else {
                this.someLogic(itemA);
                return false;
            }
        }),
        switchMap(() => this.anotherService.getItemB()),
        tap(itemB => {
            this.anotherLogic(itemB);
            this.someLogic(this.itemA);
        })
    ).subscribe();
this.myService.putItemA()
    .pipe(
        filter(itemA => {
            if (itemA.property) {
              this.itemA = itemA;
              return true;
            } else {
              this.someLogic(iteamA);
              return false;
            }
        }),
        switchMap(() => this.anotherService.getItemB()),
        tap(itemB =>{
            this.anotherLogic(itemB);
            this.someLogic(this.itemA);
        })
    ).subscribe();

Что я обнаружил в этот ответ , так это то, что это можно сделать, просто заключив общий лог c в функциональную переменную:

private prepareData= (itemA: IteamA) => pipe(
    filter(() => {
      if (itemA.property) {
        this.itemA = itemA;
        return true;
      } else {
        this.someLogic(iteamA);
        return false;
      }
    }),
    switchMap(() => this.anotherService.getItemB()),
    tap(itemB => {
        this.anotherLogic(itemB);
        this.someLogic(this.itemA);
    })
  );

, а затем используйте его следующим образом:

this.myService.putItemA()
    .pipe(
        tap(itemA=> this.temporaryIteamA = this.itemA)
        this.prepareData(this.temporaryItemA)
    ).subscribe();

но, учитывая, что мой putItemA() уже возвращает Observable<ItemA>, я хотел бы просто написать следующее:

this.myService.putItemA()
    .pipe(
        this.prepareData(itemA)
    ).subscribe();

и

this.myService.getItemA()
    .pipe(
        this.prepareData(itemA)
    ).subscribe();

Как мне изменить prepareData(), чтобы неявно получать данные?

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Всякий раз, когда вы работаете с наблюдаемыми каналами, как следует из названия, все выдаваемые значения передаются в определенный канал (смотрите его как реальный канал), поэтому вы можете выполнять любые операции, изменять значение, изменение источника излучения и многие другие сложные сценарии ios.

Тем не менее, когда вы создаете настраиваемый канал (или оператор), вы можете либо напрямую определить его как канал ...

const myPipe = pipe(
    switchMap(emmitedValue => of(`${emmitedValue} How are you?`))
);

или вы можете определить его как функцию, которая возвращает канал ...

const myPipe2 = optionalMessage => pipe(
  switchMap((emmitedValue) => of(`${emmitedValue} How are you? ${optionalMessage}`))
);

Затем вы можете использовать эти каналы, первый, передав его ссылку (вы все равно получите emmited values ​​там) и второй, вызвав эту функцию, которая возвращает желаемый канал (следовательно, вы можете передать больше параметров, чем только выбранное значение).

of('Biiz').pipe(
  map(x => `Hello ${x}!`),
  myPipe,
).subscribe(console.log);

of('Biiz').pipe(
  map(x => `Hello ${x}!`),
  myPipe2(`It's a sunny day ?`),
).subscribe(console.log);

(Вы можете проверить этот пример здесь )

В вашем случае вы должны определить свой собственный оператор, просто получив выданное значение в канале:

private prepareData = pipe(
    filter((itemA: IteamA) => {
      if (itemA.property) {
        this.itemA = itemA;
        return true;
      } else {
        this.someLogic(iteamA);
        return false;
      }
    }),
    switchMap(() => this.anotherService.getItemB()),
    tap(itemB => {
        this.anotherLogic(itemB);
        this.someLogic(this.itemA);
    })
  );

И используйте его, передав ссылку:

  this.myService.putItemA()
      .pipe(
          this.prepareData
      ).subscribe();
  
  // or
  
  this.myService.getItemA()
      .pipe(
          this.prepareData
      ).subscribe();
1 голос
/ 07 августа 2020

Думаю, вам не нужна обертка в вашем случае.

Просто попробуйте следующее:

import { pipe } from 'rxjs'

const prepareData = pipe(
  filter(itemA => {
    if (itemA.property) {
      this.itemA = itemA;
      return true;
    } else {
      this.someLogic(itemA);
      return false;
    }
  }),
  switchMap(() => this.anotherService.getItemB()),
  tap(itemB => {
    this.anotherLogic(itemB);
    this.someLogic(this.itemA);
  })
);

а затем

this.myService.getItemA().pipe(prepareData).subscribe(...)

this.myService.putItemA().pipe(prepareData).subscribe(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...