मैं rxjs में promise.then(onNextCallback,onErrorCallback)
के बराबर ढूंढ रहा हूं।
क्या ऐसा कुछ है?
pipe(concatMap(),catchError)
विकल्प वह नहीं है जिसकी मुझे तलाश है।
4 जवाब
मैंने भी इसके लिए कहा और अपना खुद का लेखन समाप्त किया।
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);
}),
);
});
वास्तव में यह मेरी जानकारी में नहीं है कि कोई भी ऑपरेटर वह करेगा जो आपको चाहिए।
हालांकि, मैं जो सुझाव देता हूं, वह अपना खुद का बनाना है।
function promiseLike<T>(
onNext: (data: T) => Observable<T>,
onError: (err: any) => Observable<any>
) {
type ErrorWrapper = {isError: boolean, err: any};
const isErrorWrapper = (err: any): err is ErrorWrapper => {
return err.isError && err.err !== undefined;
}
return function(source: Observable<T>): Observable<T> {
return source.pipe(
catchError((err) => of({isError: true, err})),
switchMap((data) => isErrorWrapper(data) ? onError(data.err) : onNext(data))
);
}
}
उपरोक्त मूल रूप से देखने योग्य स्रोत से त्रुटि को लपेटता है और फिर हम switchMap
यह तय करने के लिए कि क्या मैं onNext
और onError
चलाता हूं। इस तरह, निश्चित रूप से, onError
onNext
से आने वाली संभावित त्रुटियों को नहीं पकड़ पाएगा।
यहाँ उपयोग के उदाहरण हैं:
function getResolvingPromise(): Promise<string> {
return Promise.resolve('SUCCESS');
}
function getErrorPromise(): Promise<string> {
return Promise.reject('onError');
}
// Example with success
from(getResolvingPromise()).pipe(
promiseLike(
(data) => of(`received ${data}`),
(err) => of(3)
)
).subscribe((d) => console.log('Ex1', d)) // Logs Ex1 received SUCCESS
// Example with error
from(getErrorPromise()).pipe(
promiseLike(
(data) => of(`received ${data}`),
(err) => of(3)
)
).subscribe((d) => console.log('Ex2', d)) // Logs Ex2 3
// Example with internal error 2
from(getResolvingPromise()).pipe(
promiseLike(
(data) => throwError('Valid token not returned'),
(err) => of(3)
),
catchError(() => of('catching internal error'))
).subscribe((d) => console.log('Ex3', d)) // Logs Ex3 catching internal error
इस तरह के किसी चीज़ के बारे में क्या?
source$
ऑब्जर्वेबल सोर्स है और आप pipe
के अंदर टैप ऑपरेटर के माध्यम से संबंधित फ़ंक्शन प्रदान कर सकते हैं।
source$.pipe(
tap({ next: onNextCallback, error: onErrorCallback })
)
क्या .toPromise()
आप क्या ढूंढ रहे हैं ?
https://www.learnrxjs.io/learn-rxjs/operators/utility/topromise
फिर आप अपना .then(nextCallback)
.catch(errorCallback)
कर सकते हैं