例如下面这段代码
fromEvent(document, 'click').pipe(
map(i => {
console.log('click')
throw new Error('error')
})
).subscribe({
next: console.log,
complete: () => console.log('complete'),
error: (err) => console.log(err)
})
我以为的输出:点一下输出 click 和 error ,再点还输出 click 和 error
实际上的输出:点一下输出 click 和 error ,再点就没反应了
就算用 catchError 也一样会被关闭
事件倒还好,加个 retry 就行了,of 之类还得用 map 包起来
例如想输出 1 3 不能这么写
of(1, 2, 3).pipe(
map(i => {
if (i === 2) {
throw new Error('error')
}
return i;
}),
catchError(err => EMPTY)
).subscribe({
next: console.log,
complete: () => console.log('complete'),
error: (err) => console.log(err)
})
要这么写用 map 包起来
of(1, 2, 3).pipe(
switchMap(i => {
return of(i).pipe(
map(i => {
if (i === 2) {
throw new Error('error')
}
return i;
}),
catchError(i => EMPTY)
)
})
).subscribe({
next: console.log,
complete: () => console.log('complete'),
error: (err) => console.log(err)
})
为啥要这么设计?出来个错误把整个管子都给扬了。
RxJS 实际的业务都是怎么写的,都是加 retry 或者拿 map 包起来吗?总不能在所有 map 里写 try catch 吧。
补充一下,其实用 catchError 也可以,但是只有fromEvent 事件这类的才行。
fromEvent(document, 'click').pipe(
map(() => {
console.log('click')
throw new Error('error')
}),
catchError((err, caught) => caught)
).subscribe({
next: console.log,
complete: () => console.log('complete'),
error: (err) => console.log(err)
})
封装一个pipe供使用(供参考未测试,不清楚是否通用)
另附各种跳过继续运行的尝试解决方案参考
https://iamturns.medium.com/continue-rxjs-streams-when-errors-occur-c6a031f9a6cf
function tryCatch(tryPipe, catchCallback) {
return pipe(
switchMap(i => of(i).pipe(tryPipe, catchError(err => catchCallback(err))))
)
}
of(1, 2, 3).pipe(
tryCatch(
pipe(
map(i => {
if (i === 2) {
throw new Error('err')
}
return i
})
),
err => EMPTY,
)
).subscribe({
next: console.log,
complete: () => console.log('complete'),
error: (err) => console.log('error', err)
})
// 输出 1 3
1
66450146 2023-10-20 20:54:07 +08:00 via iPhone
|
2
Magentaize 2023-10-21 09:31:57 +08:00 via iPhone 1
materialize 了解一下
|
3
vaporSpace 2023-10-21 11:12:00 +08:00
``` js
of(1, 2, 3) .pipe( switchMap((n) => of(n).pipe( map((o) => { if (o === 2) { throw 'error'; } return o; }), catchError(() => of('EMPTY')) ) ) ) .subscribe((x) => console.log(x)); ``` 达到效果,就是有点丑 |
4
yor1g 2023-10-21 12:40:15 +08:00
EMPTY 直接走 complete 了吧 catch 返回正常值才能不会断流
|
5
Helsing 2023-10-21 15:09:32 +08:00 via iPhone 1
二楼说的 materialize 和 dematerialize 操作符是比较好处理方案
|
6
DingJZ 2023-10-23 10:15:04 +08:00
借楼问个问题,怎么能把 rx 代入日常的开发中,学了 n 次了,基本上每次用的时候现学现写,后面就忘了,下次再重来
|