소개
RxJS는 비동기 프로그래밍과 이벤트 스트림 처리를 위한 강력한 라이브러리로, Angular 같은 프레임워크에서도 널리 사용됩니다.
RxJS의 핵심 개념 중 하나인 Observable은 다양한 시점에 여러 개의 값을 방출할 수 있습니다. 때때로 이러한 Observable을 하나의 값만 반환하는 Promise로 변환하고 싶을 때가 있는데, 전통적으로 toPromise()를 사용했지만, RxJS 7에서는 더 이상 권장되지 않으며 향후 버전에서는 제거될 예정입니다.
이 글에서는 toPromise()의 대안으로 사용되는 두 가지 메서드인 firstValueFrom()과 lastValueFrom()에 대해 살펴보고, 이 둘의 차이점과 사용 사례를 예시와 함께 설명하겠습니다.
1. firstValueFrom() vs lastValueFrom()
1.1 firstValueFrom() - 첫 번째 값을 받는 방법
firstValueFrom()은 Observable에서 첫 번째로 방출되는 값을 Promise로 변환해 반환합니다. 즉, Observable 스트림에서 첫 번째 값이 방출되면 그 이후의 값은 무시되고, Promise가 resolve됩니다.
import { of, firstValueFrom } from 'rxjs';
const observable = of(1, 2, 3); // 1, 2, 3을 순차적으로 방출
const firstValue = await firstValueFrom(observable); // 첫 번째 값인 1을 반환
console.log(firstValue); // 1
위 코드에서 firstValueFrom()은 Observable이 방출한 첫 번째 값인 1을 반환합니다. 첫 번째 값이 방출되면 즉시 Observable의 나머지 값은 더 이상 신경 쓰지 않고 Promise가 완료됩니다.
실제 적용 사례
public async deleteHistory(historyId: number): Promise<ApiReturnType<void>> {
try {
const {
data: {
deleteHistory: { result, errorCode, errorMessage }
}
} = await firstValueFrom(
this.graphql.mutate(
gql`
mutation deleteHistory($historyId: Int!) {
deleteHistory(historyId: $historyId) {
result
errorCode
errorMessage
}
}
`,
{ historyId }
)
);
return { result, errorCode, errorMessage };
} catch (e) {
throw new Error(e);
}
}
1.2 lastValueFrom() - 마지막 값을 받는 방법
lastValueFrom()은 Observable에서 마지막으로 방출된 값을 Promise로 변환합니다. Observable이 완료될 때까지 기다렸다가 마지막 값을 반환하며, 스트림이 끝나지 않으면 Promise는 완료되지 않습니다.
import { of, lastValueFrom } from 'rxjs';
const observable = of(1, 2, 3); // 1, 2, 3을 순차적으로 방출
const lastValue = await lastValueFrom(observable); // 마지막 값인 3을 반환
console.log(lastValue); // 3
여기서는 Observable이 모든 값을 방출한 후, 마지막 값인 3이 반환됩니다. lastValueFrom()은 Observable이 완료될 때까지 대기하고, 그 마지막 값을 반환하는 특성이 있습니다.
2. firstValueFrom()과 lastValueFrom()의 주요 차이
두 메서드는 Observable의 값을 Promise로 변환한다는 공통점을 가지고 있지만, 반환되는 시점에 큰 차이가 있습니다:
- firstValueFrom(): Observable의 첫 번째 값을 반환하고 그 즉시 종료됩니다. 여러 개의 값을 방출하는 Observable이라 하더라도 첫 번째 값만 관심이 있을 때 사용합니다. 빠른 반환이 필요한 경우 적합합니다.
- lastValueFrom(): Observable이 완료될 때까지 기다린 후 마지막으로 방출된 값을 반환합니다. 따라서 전체 흐름을 확인한 후 최종 값만 필요할 때 적합합니다.
예시로 살펴본 차이:
- firstValueFrom()은 1, 2, 3이라는 값들이 순차적으로 방출되는 스트림에서 1만 가져오고 나머지는 무시합니다.
- 반면, lastValueFrom()은 1, 2, 3이라는 값들이 모두 방출된 후 마지막 값인 3을 가져옵니다.
3. 언제 무엇을 사용해야 할까?
3.1 firstValueFrom()을 사용하는 경우
- 첫 번째 값만 필요할 때: Observable이 여러 개의 값을 방출할 수 있지만, 처음에 방출되는 값만 사용하고 싶을 때 유용합니다.
- 빠른 응답이 필요한 경우: 전체 스트림을 기다릴 필요 없이 첫 번째 값이 방출되는 즉시 작업을 처리해야 하는 경우에 적합합니다.
3.2 lastValueFrom()을 사용하는 경우
- 마지막 값만 필요할 때: Observable의 모든 값 중 마지막 값만 사용하고자 할 때 유용합니다.
- 전체 스트림을 확인해야 할 때: 비즈니스 로직 상 전체 데이터 흐름을 보고 마지막 값만 처리할 필요가 있을 때 유용합니다.
4. 결론
RxJS 7 이후로 toPromise()가 더 이상 사용되지 않기 때문에, firstValueFrom()과 lastValueFrom()을 사용하는 것이 새로운 표준입니다. 이 두 메서드는 매우 간단하지만, Observable 스트림에서 언제 값을 받을지에 따라 큰 차이를 만들어냅니다.
따라서, Observable에서 값을 Promise로 변환할 때는 어떤 값을 받을지와 언제 받을지를 잘 고려한 후 이 두 메서드를 선택하는 것이 중요합니다.
- 빠르게 첫 번째 값을 받아야 한다면 firstValueFrom()을,
- 스트림의 마지막 값을 받아야 한다면 lastValueFrom()을 사용하세요.
이를 통해 RxJS를 더 유연하게 사용할 수 있으며, 코드의 가독성과 유지보수성도 크게 향상될 것입니다.
'개발 공부' 카테고리의 다른 글
| URL의 정의와 기본 개념 (9) | 2024.10.06 |
|---|---|
| HTML5 (1) | 2024.10.06 |
| Promise.all / TypeScript (0) | 2024.07.16 |
| Node.js (0) | 2024.07.15 |
| 동기(synchronous) 와 비동기(asynchronous) 함수 (0) | 2024.07.15 |