如何从另一个 .pipe() 内部将参数传递给包装的“.pipe()”逻辑
How to pass parameters to wrapped '.pipe()' logic from inside of another .pipe()
我必须为不同的服务调用执行相同的逻辑(例如:myService.getA()
和 myService.putA()
)。该逻辑包括其他服务调用,因此我从 .pipe()
.
中进行这些调用
我现在的逻辑是这样的:
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();
我在 中发现的是,它可以通过将共享逻辑包装在函数变量中来完成:
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()
已经 returns 一个 Observable<ItemA>
我想像下面这样写:
this.myService.putItemA()
.pipe(
this.prepareData(itemA)
).subscribe();
和
this.myService.getItemA()
.pipe(
this.prepareData(itemA)
).subscribe();
我应该如何修改 prepareData()
以隐式接收数据?
我认为您的情况不需要包装纸。
只需尝试以下操作:
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(...)
每当你使用 Observable 管道时,顾名思义,所有的 emmited 值都会 piped 进入定义的管道(将其视为真实管道),因此你可以做任何操作,修改值,改变发射源,以及更多更复杂的场景。
也就是说,当您创建自定义管道(或运算符)时,您可以直接将其定义为管道...
const myPipe = pipe(
switchMap(emmitedValue => of(`${emmitedValue} How are you?`))
);
或者您可以将其定义为 return 管道的函数...
const myPipe2 = optionalMessage => pipe(
switchMap((emmitedValue) => of(`${emmitedValue} How are you? ${optionalMessage}`))
);
然后你可以使用这些管道,第一个通过传递它的引用(你仍然会在那里收到 emmited 值),第二个通过调用 return 所需管道的函数(因此你可以传递的参数不仅仅是 emmited 值)。
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);
(你可以检查那个例子here)
对于您的情况,您应该通过在管道中接收发射值来定义自定义运算符:
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();
我必须为不同的服务调用执行相同的逻辑(例如:myService.getA()
和 myService.putA()
)。该逻辑包括其他服务调用,因此我从 .pipe()
.
我现在的逻辑是这样的:
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();
我在
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()
已经 returns 一个 Observable<ItemA>
我想像下面这样写:
this.myService.putItemA()
.pipe(
this.prepareData(itemA)
).subscribe();
和
this.myService.getItemA()
.pipe(
this.prepareData(itemA)
).subscribe();
我应该如何修改 prepareData()
以隐式接收数据?
我认为您的情况不需要包装纸。
只需尝试以下操作:
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(...)
每当你使用 Observable 管道时,顾名思义,所有的 emmited 值都会 piped 进入定义的管道(将其视为真实管道),因此你可以做任何操作,修改值,改变发射源,以及更多更复杂的场景。
也就是说,当您创建自定义管道(或运算符)时,您可以直接将其定义为管道...
const myPipe = pipe(
switchMap(emmitedValue => of(`${emmitedValue} How are you?`))
);
或者您可以将其定义为 return 管道的函数...
const myPipe2 = optionalMessage => pipe(
switchMap((emmitedValue) => of(`${emmitedValue} How are you? ${optionalMessage}`))
);
然后你可以使用这些管道,第一个通过传递它的引用(你仍然会在那里收到 emmited 值),第二个通过调用 return 所需管道的函数(因此你可以传递的参数不仅仅是 emmited 值)。
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);
(你可以检查那个例子here)
对于您的情况,您应该通过在管道中接收发射值来定义自定义运算符:
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();