RxJS Create Operator
Operators는 Observable에서 작동되는 method들이다. (.map(...)
, .filter(...)
, .merge(...)
…) 이들은 실행되면 현재 Observable의 인스턴스를 바꾸지는 않는다.
다만 첫번째 Observable의 subscription 로직을 기반으로 새로운 Observable을 return한다. 따라서 이전의 Observable은 수정되거나 하지 않는다(immutability).
Operator는 필수적으로 Observable를 취하고, 새로운 Observable을 생성하는 순수함수이다.
우선 이번 페이지에서는 Observable을 생성하는 Operators를 살펴보려고 한다.
bindCallback
인자로는 3개를 받는데, 1.콜백이 포함된 함수
, 2.출력될 옵저버블에 전달할 값
, 3.스케줄러
로 구성된다. 해당 함수의 마지막 인자를 콜백으로 실행시킨다.아래는 getJSON
의 예제이다.
1 | const getJSONAsObservable = Rx.Observable.bindCallback(jQuery.getJSON); |
defer
defer는 스트림의 실행을 미루는 method이다. 인자는 옵저버블이나 프라미스 객체를 리턴하는 함수를 받으며 observable을 생성한다. 따라서 defer가 어떤 observable을 리턴하느냐에 따라서 스트림이 결정된다.
public static defer(observableFactory: function(): Observable or Promise): Observable
1 | const clicksOrInterval = Rx.Observable.defer(function () { |
empty
empty는 빈 스트림을 반환한다. 일단 스트림을 만들고 동적으로 값을 생성하거나 할 때, 혹은 조건에 따라 동적으로 다른 스트림을 만들때 쓰일것으로 보인다.1
2const result = Rx.Observable.empty().startWith(7);
result.subscribe(x => console.log(x)); //7
1 | const interval = Rx.Observable.interval(1000); |
from
가장많이 쓰이는 생성 operator중 하나일것이다. 인자로는 Observable로 변환시킬 수 있는 모든 값을 받을 수 있다. 구독가능한 객체, Promise 객체, 배열, 유사배열, 이터러블 인터페이스를 따르는 값들이 된다. iterable interface는 ES6에 추가된 문법으로 이에 해당되는 것으로는 배열, 문자열, gernerator 함수로 부터 도출된 interator 객체, Map 객체, Set 객체 등이다.
가장 기본적인 from method형태. 배열을 인자로 받아 스트림을 생성한다.1
2
3
4
5
6const input = Rx.Observable.from([1,2,3,4]);
input.subscribe(function(i){
console.log(i)
},'',function(){
console.log('completed')
}); //1, 2, 3, 4, 'completed'
from은 generator 함수로부터 생성된 interator객체도 인자로 받을 수 있다. generator에 대한 자세한 설명은 여기를 참조.1
2
3
4
5
6
7
8
9
10
11
12
13
14function* generateDoubles(seed) {
var i = seed;
while (i<100) {
yield i;
i = 2 * i; // double it
}
}
var iterator = generateDoubles(3);
var result = Rx.Observable.from(iterator);
result.subscribe(
x => console.log(x),
e => console.error(e),
() => console.log('finished'));
})
앞서 야기 한대로, from operator는 promise도 받는다.1
2
3
4
5
6
7const data = fetch('https://api.zigbang.com/v1/search/subway?q=').then(data=>{
return data.json();
});
var ob = Rx.Observable.from(data).flatMap(x=>x);
ob.subscribe(e=>{
console.log(e.name); //지하철역들...
})
fromEvent
특정 이벤트 타입의 실행을 관찰하는 Operator다. 첫번째 인자로 이벤트가 발생하는 타겟(DOM 엘리먼트), 두번째로 이벤트 타입(click
, keyup
등)을 받는다.1
2const clicks = Rx.Observable.fromEvent(document, 'click');
clicks.subscribe(x => console.log(x));
fromEventPattern
API기반의 addHandler
/removeHandler
로부터 Observable
을 생성하는 operator다.1
2
3
4
5
6
7
8function addClickHandler(handler) {
document.addEventListener('click', handler);
}
function removeClickHandler(handler) {
document.removeEventListener('click', handler);
}
var clicks = Rx.Observable.fromEventPattern(addClickHandler,removeClickHandler);
clicks.subscribe(x => console.log(x));
fromEventPattern은 특정 플러그인에서 사용되는 이벤트를 Observable
로 사용할 때 용이하다. 예를 들어 구글 지도 API에 idle
이라는 이벤트가 있다. 이 이벤트를 관찰하는 observable을 만들려면 아래처럼 사용할 수 있다.1
2
3
4const idle$ = function (handler){
google.maps.event.addListener(map, 'idle', handler);
}
Rx.Observable.fromEventPattern(idle$)
fromPromise
Promise를 Observable로 컨버팅한다. 만일 Promise가 resolve된다면 resolved value를 Observable로 넘긴다. 만일 Promise가 reject되면 Observable error를 넘긴다. 아래는 Promise
객체를 반환하는 fetch 함수를 이용해서 Observable를 생성한 예제이다. 하지만 위에서 설명한 from
operator가 Promise
객체를 받을 수 있기 때문에 큰 활용성은 없어 보인다.1
2var result = Rx.Observable.fromPromise(fetch('http://myserver.com/'));
result.subscribe(x => console.log(x), e => console.error(e));
never
아무것도 방출(emit)하지 않는 Observable을 생성한다. 이 정적 operator는 값이나 오류도 없으며 subscribe도 내보내지 않는 간단한 Observable을 만든다. 테스트(TDD, BDD) 목적으로 사용할때 유용하다고 하는데 직접 써본적은 없다. 자동으로 subscribe하지 않기 때문에 subscribe를 해줘야 실행된다.
1 | function info() { |
위 예제는 실제로 subscribe되지만 아무것도 실행되지 않는다.
of
아주 정직한 operator다. 인자를 하나씩 내보내고, 모두 내보내면 스트림이 끝난다.1
2var letters = Rx.Observable.of('a', 'b', 'c');
letters.subscribe(x => console.log(x)); // a--b--c