RxDart는 비동기 프로그래밍을 위한 인기 있는 reactiveX API의 구현체로, 기본 Dart Streams API를 활용합니다.
=>
ReactiveX (Reactive Extensions)는 비동기 및 이벤트 기반 프로그램을 구성하기 위한 API입니다. Observable sequences를 사용하여 비동기 데이터 스트림을 나타내고, 이러한 스트림에 대한 연산을 적용할 수 있는 연산자를 제공합니다.
ReactiveX는 다양한 프로그래밍 언어에 적용될 수 있으며, 각 언어별로 독특한 구현이 있습니다. 예를 들면, RxJava는 Java를 위한 ReactiveX 구현이고, RxJS는 JavaScript를 위한 것입니다.
기본적으로 ReactiveX는 데이터의 흐름과 변화에 반응하여 프로그래밍하는 패러다임을 제공합니다. 이를 통해 복잡한 비동기 로직을 더 간단하고, 직관적으로 표현할 수 있게 해줍니다.
=>
ReactiveX (Reactive Extensions)는 API의 모음이며, 일반적으로 인터페이스 또는 추상화로 생각할 수 있습니다. ReactiveX는 비동기 및 이벤트 기반 프로그래밍을 위한 패턴과 연산자를 정의합니다. 이러한 패턴과 연산자는 다양한 프로그래밍 언어와 플랫폼에서 재구현될 수 있습니다.
ReactiveX의 핵심 개념 중 하나는 "Observable"이라는 데이터 스트림을 나타내는 추상화입니다. Observable은 데이터 항목을 방출하거나 오류를 방출하거나 완료 신호를 방출할 수 있습니다. 이러한 Observable에 연산을 수행하는 연산자(operator)들도 정의됩니다.
따라서, ReactiveX API는 Observable, Observer, 연산자 등의 인터페이스 및 기본적인 패턴을 정의하는 추상화로 생각할 수 있습니다. 여기에 기반하여 다양한 언어와 플랫폼에서 구체적인 구현이 제공됩니다.
RxDart는 Dart Streams와 StreamControllers의 기능을 확장합니다.
Dart는 기본적으로 매우 적절한 Streams API를 제공합니다. 이 API에 대안을 제공하려는 시도 대신, RxDart는 이 API 위에 reactive extensions 사양의 기능을 추가합니다.
RxDart는 Dart Streams를 대체하기 위한 자체 Observable 클래스를 제공하지 않습니다. 대신 여러 추가적인 Stream 클래스, 연산자 (Stream 클래스의 확장 메서드), 그리고 Subjects를 제공합니다.
다른 언어에서의 Observables에 익숙하다면, Rx Observables와 Dart Streams 간의 주요 차이점을 보여주는 비교 차트를 확인해보세요.
=>
많은 상황에서 Streams와 Observables는 동일한 방식으로 작동합니다. 그러나 표준 Rx Observables에 익숙하다면, Stream API의 일부 기능은 당신을 놀라게 할 수 있습니다. 아래에는 이러한 차이점을 이해하는 데 도움을 주는 표를 포함하였습니다.
아래 상황에 대한 추가 정보는 Rx 클래스 문서를 읽음으로써 확인할 수 있습니다.
=> RxDart doc은 곧 뽀갠다. 기다리시라.
상황 | Rx Observables | Dart Streams |
---|---|---|
오류가 발생했을 때 | Observable은 오류와 함께 종료됨 | 오류가 발생하면 Stream은 계속됨 |
Cold Observables | 여러 구독자가 동일한 cold Observable을 수신 | 단일 구독자만 가능 |
Hot Observables | 있음 | 있음, Broadcast Streams로 알려짐 |
{Publish, Behavior, Replay}Subject가 hot한가? | 예 | 예 |
Single/Maybe/Completable 지원? | 예 | 예, rxdart_ext의 Single을 사용 (Completable = Single, Maybe = Single<T?>) |
백 프레셔(Back pressure) 지원 | 예 | 예 |
null을 전달할 수 있나? | 예, RxJava 제외 | 예 |
기본적으로 동기적인가? | 예 | 아니오 |
구독을 일시 중지/재개할 수 있나? | 아니오 | 예 |
pub.dev에 보면 코나미 코드를 읽는 법이라고 샘플 코드가 나온다.
해당 코드는 웹페이지에서 Konami Code (위, 위, 아래, 아래, 왼쪽, 오른쪽, 왼쪽, 오른쪽, B, A) 를 입력받았을 때, 웹 페이지 내의 특정 요소에 'KONAMI!'라는 텍스트를 표시하는 기능을 담고 있다.
컨트롤러 조작이 본 기기(CPU...?)에 즉각 전달되고 반응이 나타나야 하니
Stream 관련 예제로 좋은 거 같다.
코드는 다음과 같다.
import 'package:rxdart/rxdart.dart';
void main() {
const konamiKeyCodes = <int>[
KeyCode.UP,
KeyCode.UP,
KeyCode.DOWN,
KeyCode.DOWN,
KeyCode.LEFT,
KeyCode.RIGHT,
KeyCode.LEFT,
KeyCode.RIGHT,
KeyCode.B,
KeyCode.A,
];
final result = querySelector('#result')!;
document.onKeyUp
.map((event) => event.keyCode)
.bufferCount(10, 1) // An extension method provided by rxdart
.where((lastTenKeyCodes) => const IterableEquality<int>().equals(lastTenKeyCodes, konamiKeyCodes))
.listen((_) => result.innerHtml = 'KONAMI!');
}
Konami Code를 나타내는 키보드 키 코드들을 순서대로 리스트에 저장
-> 웹페이지에서 #result라는 id를 가진 요소를 선택하고 그것을 result 변수에 할당
-> 문서의 onKeyUp 이벤트를 수신하여 사용자가 키보드의 키를 눌렀을 때 발생하는 이벤트를 감지
-> 감지된 이벤트에서 키 코드를 추출하고, 그것을 다른 스트림으로 변환
-> RxDart의 bufferCount 메소드를 사용하여 최근 10개의 키 코드 이벤트를 그룹화하고 새로운 키 코드 이벤트가 들어올 때마다 이전의 키 코드 리스트를 업데이트
-> where 메소드를 사용하여 최근 10개의 키 코드가 Konami Code와 일치하는지 확인
-> Konami Code와 일치하는 키 코드 시퀀스가 감지되면, 'KONAMI!'라는 텍스트를 웹페이지의 result 요소에 표시
기본적인 RxDart 연산자 사용: 이 코드는 RxDart의 기본 연산자 중 몇몇을 사용하고 있습니다. 예를 들어, map, bufferCount, 그리고 where는 RxDart의 연산자 중 일부입니다. 이들 연산자의 사용법을 보여주기 위해 이 샘플 코드가 선택되었을 가능성이 큽니다.
이해하기 쉬운 예제: Konami Code는 많은 개발자 및 게이머에게 잘 알려져 있습니다. 따라서 이를 통한 예제는 대부분의 사용자가 쉽게 이해할 수 있을 것입니다.
실제 응용 사례: 이 예제는 실제 웹 애플리케이션에서 특정 시퀀스의 입력을 감지하고 반응하는 방법을 보여주므로 실제 문제 해결에 유용한 방법을 제시합니다.
스트림의 시퀀스 처리: RxDart는 비동기 데이터 시퀀스를 처리하는데 초점을 맞추고 있습니다. 이 예제는 시간에 따른 키 이벤트 시퀀스를 처리하는 방법을 보여주므로 RxDart의 핵심 기능을 잘 나타냅니다.
직관적인 결과: 이 샘플 코드를 실행하면, Konami Code가 올바르게 입력되었을 때 바로 웹 페이지에 결과가 표시되므로 결과를 즉시 확인할 수 있습니다.
이제 API OVERVIEW로 넘어간다.
레쯔기릿