javascript - rxjs - 同时具有 on-next 和 on-error 回调的运算符?
问题描述
我正在寻找promise.then(onNextCallback,onErrorCallback)
rxjs 中的等价物。
有这样的吗?
pipe(concatMap(),catchError)
替代品不是我要找的。
解决方案
我也要求这个,最后写了我自己的。
import * as RxJS from 'rxjs';
/**
* Like `promise.then(onFulfilled, onRejected)`. This is *not* the same as
* `map(onNext).catchError(onError)`, because this operator will only catch errors resulting from
* the original observable—not errors resulting from `onNext`.
*/
export const mapOrCatchError = <T, B>(
onNext: (value: T) => B,
onError: (value: unknown) => B,
): RxJS.OperatorFunction<T, B> => ob$ =>
new RxJS.Observable<B>(observer =>
ob$.subscribe({
next: t => {
let next: B;
try {
next = onNext(t);
} catch (error) {
observer.error(error);
return;
}
observer.next(next);
},
error: error => {
let next: B;
try {
next = onError(error);
} catch (newError) {
observer.error(newError);
return;
}
observer.next(next);
observer.complete();
},
complete: () => {
observer.complete();
},
}),
);
测试:
import { marbles } from 'rxjs-marbles/jest';
import { mapOrCatchError } from '../operators';
describe('mapOrCatchError', () => {
it(
'should map',
marbles(m => {
const source$ = m.cold('--(a|)', { a: 1 });
const expected = ' --(b|)';
const actual$ = source$.pipe(
mapOrCatchError(
a => a + 1,
_error => 0,
),
);
m.expect(actual$).toBeObservable(expected, { b: 2 });
}),
);
it(
'should catch',
marbles(m => {
const source$ = m.cold('--#');
const expected = ' --(a|)';
const actual$ = source$.pipe(
mapOrCatchError(
a => a + 1,
_error => 0,
),
);
m.expect(actual$).toBeObservable(expected, { a: 0 });
}),
);
it(
'should error if error handler throws',
marbles(m => {
const source$ = m.cold('--#');
const expected = ' --#';
const error = new Error('foo');
const actual$ = source$.pipe(
mapOrCatchError(
a => a + 1,
_error => {
throw error;
},
),
);
m.expect(actual$).toBeObservable(expected, undefined, error);
}),
);
it(
'should not catch errors thrown by map function',
marbles(m => {
const source$ = m.cold('--(a|)');
const expected = ' --#';
const error = new Error('foo');
const actual$ = source$.pipe(
mapOrCatchError(
() => {
throw error;
},
_error => 'caught error',
),
);
m.expect(actual$).toBeObservable(expected, undefined, error);
}),
);
});
推荐阅读
- python - 无法使用熊猫将大数据元组转换为数据框
- javascript - Issue with infite fetch loop using useEffect
- elasticsearch - 深入了解 Kibana 脚本字段
- redis - 如何在存储其他动态数据的同时利用 Redis 的地理空间功能
- javascript - Datamap 插件不显示地图
- javascript - Formatter AxisLabel Echarts fontWeight 不起作用
- javascript - 无法使用 nuxtjs 在生产中的异步数据中获取路由参数或查询
- java - 日志中的线程轮询计数超过池大小
- laravel - 具有自动令牌更新功能的 Vue + Laravel + Gmail API
- wordpress - 如何在 Woocommerce 中自定义帐单地址的详细地址?