如何在 rxjs 管道中有条件地做某事?
How to do conditionally something in rxjs pipe?
有人能告诉我带条件操作的 rxjs 管道的正确语法是什么吗?
在这种情况下,如果环境名称数组长度不是 1,我想使用过滤器进行映射。如何在没有 return 的情况下使用 if 语句?有没有 rxjs 运算符?
environmentName = ['env1', 'env2'];
sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)), //[["stylesheet","env1-xyz"],["include","cable"],...]
// if(this.environmentName.length!==1){
map((sourceList) => sourceList.filter((scr) => scr[1].startsWith(this.environmentName[0]) || scr[0] === 'include')),
//}
repeatWhen(() => this.sourceListChanged$)
);
Could somebody tell me what is the right syntax for an rxjs pipe with a conditional operation?
如果客户端软件已经从源管道传输,filter
是一种提供快速解决方案的工具。从过滤器返回 true
将继续管道。返回 false
将从管道中删除该值。返回 false 不影响底层订阅。
const source$ = /* snip */;
source$.pipe(
filter((v) => v % 2 === 0) // non-even values do not continue
tap((v) => {
console.log("Even value received: ", v);
})
).subscribe(
/* snip */
)
如果需要新的来源,那么 iif
是合适的。
iif(
() => someCondition, // if someCondition
() => sourceA$, // then return sourceA
() => sourceB$, // else return sourceB
).pipe(
/* pipe the source returned from `iif` */
).subscribe(
/* subscribe to the source returned from `iif` */
)
根据您的示例,您要检查的条件是数组的长度是 1 (false) 还是不是 (true)。
if the enviroment name array lenght is not 1
我已经将您在 CodePen 上的代码改编为一个独立的例子,这里是一个例子:
const environmentName = ['env1', 'env2'];
sourceList$.pipe(
tap((sourceList) => console.log("Source list: ", sourceList)),
filter(() => environmentName.length !== 1)
).subscribe(
/* snip */
);
您的代码失败,因为您正在执行相反的检查。在您的示例中,仅当长度为 1 时管道才会继续。由于数组是硬编码的并且长度为 2,因此过滤器永远不会通过。
提到iif
不是运算符。使用例如mergeMap
将其合并到您的代码中:
environmentName = ['env1', 'env2'];
const filterSourceListByEnv1OrInclude = srcList => srcList.filter((scr) => scr[1].startsWith(this.environmentName[0]) || scr[0] === 'include');
sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)),
mergeMap(srcList => iff(
() => this.environmentName.length !== 1,
of(filterSourceListByEnv1OrInclude(srcList)),
of(srcList)
)),
repeatWhen(() => this.sourceListChanged$)
);
或者可以使用三元运算符代替 iif
:
sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)),
mergeMap(srcList => of(this.environmentName.length !== 1
? filterSourceListByEnv1OrInclude(srcList)
: srcList
)),
repeatWhen(() => this.sourceListChanged$)
);
有人能告诉我带条件操作的 rxjs 管道的正确语法是什么吗? 在这种情况下,如果环境名称数组长度不是 1,我想使用过滤器进行映射。如何在没有 return 的情况下使用 if 语句?有没有 rxjs 运算符?
environmentName = ['env1', 'env2'];
sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)), //[["stylesheet","env1-xyz"],["include","cable"],...]
// if(this.environmentName.length!==1){
map((sourceList) => sourceList.filter((scr) => scr[1].startsWith(this.environmentName[0]) || scr[0] === 'include')),
//}
repeatWhen(() => this.sourceListChanged$)
);
Could somebody tell me what is the right syntax for an rxjs pipe with a conditional operation?
如果客户端软件已经从源管道传输,filter
是一种提供快速解决方案的工具。从过滤器返回 true
将继续管道。返回 false
将从管道中删除该值。返回 false 不影响底层订阅。
const source$ = /* snip */;
source$.pipe(
filter((v) => v % 2 === 0) // non-even values do not continue
tap((v) => {
console.log("Even value received: ", v);
})
).subscribe(
/* snip */
)
如果需要新的来源,那么 iif
是合适的。
iif(
() => someCondition, // if someCondition
() => sourceA$, // then return sourceA
() => sourceB$, // else return sourceB
).pipe(
/* pipe the source returned from `iif` */
).subscribe(
/* subscribe to the source returned from `iif` */
)
根据您的示例,您要检查的条件是数组的长度是 1 (false) 还是不是 (true)。
if the enviroment name array lenght is not 1
我已经将您在 CodePen 上的代码改编为一个独立的例子,这里是一个例子:
const environmentName = ['env1', 'env2'];
sourceList$.pipe(
tap((sourceList) => console.log("Source list: ", sourceList)),
filter(() => environmentName.length !== 1)
).subscribe(
/* snip */
);
您的代码失败,因为您正在执行相反的检查。在您的示例中,仅当长度为 1 时管道才会继续。由于数组是硬编码的并且长度为 2,因此过滤器永远不会通过。
提到iif
不是运算符。使用例如mergeMap
将其合并到您的代码中:
environmentName = ['env1', 'env2'];
const filterSourceListByEnv1OrInclude = srcList => srcList.filter((scr) => scr[1].startsWith(this.environmentName[0]) || scr[0] === 'include');
sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)),
mergeMap(srcList => iff(
() => this.environmentName.length !== 1,
of(filterSourceListByEnv1OrInclude(srcList)),
of(srcList)
)),
repeatWhen(() => this.sourceListChanged$)
);
或者可以使用三元运算符代替 iif
:
sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)),
mergeMap(srcList => of(this.environmentName.length !== 1
? filterSourceListByEnv1OrInclude(srcList)
: srcList
)),
repeatWhen(() => this.sourceListChanged$)
);