Использование метода asyn c в Rx JS NextObserver - PullRequest
3 голосов
/ 26 мая 2020

Я пытаюсь использовать функцию asyn c в перехватчике Nest JS. Эти перехватчики используют Rx JS Observables следующим образом:

@Injectable()
export class MyInterceptor implements NestInterceptor {
    async intercept<T>(context: ExecutionContext, next: CallHandler): Promise<Observable<T>> {
        await doBegin();
        return next
            .handle()
            .pipe(
                tap(
                    () => console.log("Done"),
                    (e) => console.error(e)
                )
            );
    }
}

Это работает, но что, если я хочу, чтобы методы в tap были асинхронными c? Подпись метода :

(value: T) => void

Могу я просто поместить туда метод asyn c? Или мне следует использовать другой подход?

1 Ответ

1 голос
/ 26 мая 2020

Если вы хотите, чтобы он был асинхронным c и его ошибка должна быть обнаружена, вам необходимо использовать mergeMap или любой другой подходящий оператор для его обработки внутри контекста потока, потому что tap вызывает побочные эффекты за пределами stream.

const myAsyncFunction = () => {
  // a sample of promise.
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('Promise!');
      resolve();
    }, 1000);
  });
}
@Injectable()
export class MyInterceptor implements NestInterceptor {
    async intercept<T>(context: ExecutionContext, next: CallHandler): Promise<Observable<T>> {
        await doBegin();
        return next
            .handle()
            .pipe(
                mergeMap(value => from(myAsyncFunction()).pipe(
                  ignoreElements(),
                  // catchError(() => EMPTY), // catching all errors.
                  endWith(value),
                )),
                tap(
                  () => {}, // nothing to do here, we need error.
                  (e) => console.error(e), // or catchError if you wan't to handle it.
                ),
            );
    }
}

, если вас не волнуют его ошибки - просто позвоните .then.

@Injectable()
export class MyInterceptor implements NestInterceptor {
    async intercept<T>(context: ExecutionContext, next: CallHandler): Promise<Observable<T>> {
        await doBegin();
        return next
            .handle()
            .pipe(
                tap(
                  myAsyncFunction, // if it returns `new Promise` - it will work.
                  (e) => console.error(e),
                ),
            );
    }
}
...