RxJS 在执行 first 或 find 后不会执行管道运算符
RxJS won't execute pipe operators after executing either first or find with a false predicate
我有这个可观察的订阅
this.tooltipEventSubject.pipe(
filter(event => event.type === "show"),
tap(() => this.tooltipContent.loading = true),
filter(() => this.messageContent?.sender !== undefined && this.tooltipContent.success === undefined),
mergeMap(() => this.jabService.searchEntityInAddressBook(this.messageContent?.sender ?? "")),
mergeMap(response => response.values),
filter(response => response !== undefined) as OperatorFunction<Entity | undefined, Entity>,
tap(() => console.log("before first")),
find(entity => entity.name === this.messageContent?.sender),
tap(() => console.log("after first")),
).subscribe({
next: () => console.log("next"),
error: err => console.log(err),
complete: () => console.log("complete")
})
它命中“查找”谓词(使用调试器检查)然后什么都不做。
我尝试了很多运算符,比如先跟一个 catchError,在这个例子中我找到了。
它正在进入“before first”,但随后不会打印任何其他内容。我知道 find 谓词是 returning false,它应该。但为什么它会停止 运行 ?它不应该 return 对以下运算符“未定义”吗?它甚至不应该打印“完成”吗?
感谢您的回答
如果您的谓词 return 为假,这意味着没有符合您条件的值,并且 'find' 运算符在这种情况下不会 return 任何值。
查看官方 rxjs 文档了解更多信息:https://rxjs.dev/api/operators/find
find
运算符将等到谓词 returns 为真,直到那时它不会发出任何数据,即使 undefined
.
find
仅当 source observable
完成 和 none 数据匹配时才会发出 undefined
。
在你的例子中,source observable 是一个表单事件,所以除非你这样做,否则它不会完成。Ex.takeUntil ..
我提供了两个例子。
Ex. 1
from([1, 2, 3, 4]).pipe(
tap((data) => console.log('Before find', data)),
find((data) => data > 5),
tap((data) => console.log('After find', data))
)
.subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed'),
});
输出:
Before find 1
Before find 2
Before find 3
Before find 4
After find undefined
undefined
Completed
Ex. 2
<button id="btnFind">Find</button>
const btnFind = document.getElementById('btnFind');
let count: number = 0;
fromEvent(btnFind, 'click')
.pipe(
tap(() => count++),
// takeUntil(timer(5000)),
tap((count) => console.log('Before find', count)),
find(() => count > 4),
tap((count) => console.log('After find', count))
)
.subscribe({
next: (e) => console.log(e),
error: console.error,
complete: () => console.log('Completed'),
});
在第二个例子中它会在第 5 次点击后发出,或者如果你取消注释 takeUntil
然后在 5 秒后
我有这个可观察的订阅
this.tooltipEventSubject.pipe(
filter(event => event.type === "show"),
tap(() => this.tooltipContent.loading = true),
filter(() => this.messageContent?.sender !== undefined && this.tooltipContent.success === undefined),
mergeMap(() => this.jabService.searchEntityInAddressBook(this.messageContent?.sender ?? "")),
mergeMap(response => response.values),
filter(response => response !== undefined) as OperatorFunction<Entity | undefined, Entity>,
tap(() => console.log("before first")),
find(entity => entity.name === this.messageContent?.sender),
tap(() => console.log("after first")),
).subscribe({
next: () => console.log("next"),
error: err => console.log(err),
complete: () => console.log("complete")
})
它命中“查找”谓词(使用调试器检查)然后什么都不做。
我尝试了很多运算符,比如先跟一个 catchError,在这个例子中我找到了。
它正在进入“before first”,但随后不会打印任何其他内容。我知道 find 谓词是 returning false,它应该。但为什么它会停止 运行 ?它不应该 return 对以下运算符“未定义”吗?它甚至不应该打印“完成”吗?
感谢您的回答
如果您的谓词 return 为假,这意味着没有符合您条件的值,并且 'find' 运算符在这种情况下不会 return 任何值。
查看官方 rxjs 文档了解更多信息:https://rxjs.dev/api/operators/find
find
运算符将等到谓词 returns 为真,直到那时它不会发出任何数据,即使 undefined
.
find
仅当 source observable
完成 和 none 数据匹配时才会发出 undefined
。
在你的例子中,source observable 是一个表单事件,所以除非你这样做,否则它不会完成。Ex.takeUntil ..
我提供了两个例子。
Ex. 1
from([1, 2, 3, 4]).pipe(
tap((data) => console.log('Before find', data)),
find((data) => data > 5),
tap((data) => console.log('After find', data))
)
.subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed'),
});
输出:
Before find 1
Before find 2
Before find 3
Before find 4
After find undefined
undefined
Completed
Ex. 2
<button id="btnFind">Find</button>
const btnFind = document.getElementById('btnFind');
let count: number = 0;
fromEvent(btnFind, 'click')
.pipe(
tap(() => count++),
// takeUntil(timer(5000)),
tap((count) => console.log('Before find', count)),
find(() => count > 4),
tap((count) => console.log('After find', count))
)
.subscribe({
next: (e) => console.log(e),
error: console.error,
complete: () => console.log('Completed'),
});
在第二个例子中它会在第 5 次点击后发出,或者如果你取消注释 takeUntil
然后在 5 秒后