मैं rxjs में promise.then(onNextCallback,onErrorCallback) के बराबर ढूंढ रहा हूं।

क्या ऐसा कुछ है?

  • pipe(concatMap(),catchError) विकल्प वह नहीं है जिसकी मुझे तलाश है।
3
Stav Alfi 11 सितंबर 2020, 23:54

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);
    }),
  );
});
2
Oliver Joseph Ash 15 सितंबर 2020, 18:36

वास्तव में यह मेरी जानकारी में नहीं है कि कोई भी ऑपरेटर वह करेगा जो आपको चाहिए।

हालांकि, मैं जो सुझाव देता हूं, वह अपना खुद का बनाना है।

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
1
Guilhermevrs 13 सितंबर 2020, 16:18

इस तरह के किसी चीज़ के बारे में क्या?

source$ ऑब्जर्वेबल सोर्स है और आप pipe के अंदर टैप ऑपरेटर के माध्यम से संबंधित फ़ंक्शन प्रदान कर सकते हैं।

source$.pipe(
  tap({ next: onNextCallback, error: onErrorCallback })
)
0
Goga Koreli 12 सितंबर 2020, 00:31

क्या .toPromise() आप क्या ढूंढ रहे हैं ?

https://www.learnrxjs.io/learn-rxjs/operators/utility/topromise

फिर आप अपना .then(nextCallback) .catch(errorCallback) कर सकते हैं

0
tawfik nasser 12 सितंबर 2020, 03:41