본문 바로가기

개발이나하자../frontend

[RxJS] RxJS기초1 | RxJS는 언제 쓰나요? | Observable? Observer? Subscription?

요즘에 알고리즘 공부만 하고 있다. 공부할 건 많은데 어디서 어떻게 시작해야 할지 모르겠다. 

RxJS는 예전부터 공부해보고싶었던 부분이긴 한데.. RxJS는 정말 어렵다. 왜 이렇게 다 어려울까 ..ㅎ

사실 공부하면 어려운 건 없지.. 못할 것도 없지 ^^!

시간 있을 때 공부해보자~ 어떻게 할까 하다가 유튜브 강의 듣기로 결정!

 

 

https://www.learnrxjs.io/

 

https://www.youtube.com/watch?v=Tux1nhBPl_w&list=PL55RiY5tL51pHpagYcrN9ubNLVXF8rGVi&index=2

유튜브를 보고 RxJS 기초를 공부해 본다.

여기서 JS Bin이라는 사이트를 이용해봤다. 별로인데 잠깐 연습하기엔 괜찮다.

https://jsbin.com/?html,js,console,output

 

JS Bin

Sample of the bin:

jsbin.com

 

 

Add library 버튼을 클릭하고 RxJS를 선택하면 RxJS를 사용 할 수 있게 script가 추가된다.

 

 

버튼을 생성해보었다. Output 부분에 버튼이 생긴 것을 볼 수 있다.

 

// 버튼을 잡는다
var button = document.querySelector('button');

// Rx 사용 방법. 버튼을 클릭했을 때 ..? 마우스 이벤트의 clientX값을 출력한다.
Rx.Observable.fromEvent(button, 'click').
  subscribe((value) => console.log(value.clientX));

 

버튼을 클릭했을 때 그냥 이벤트 정보를 콘솔에 찍는 코드다. RxJS를 이런 식으로 쓸 수 있다는 것을 보여주는 듯.

이 유튜브에서 얘기하는 건.. 이 Observable이 정말 유용한 것은 정말 많고 다양한 method가 많이 때문이다 라고 설명한다.

Rx.Observable.fromEvent(button, 'click')
  .throttleTime(1000)
  .map((data) => {return data.clientY})
  .subscribe((coordinate) => console.log(coordinate) );


// 위 코드는 버튼을 막 클릭했을 때 콘솔에 계쏙 data.clientY 정보가 찍히지 않고
// throttleTime(1000) 을 이용해서 아무리 많은 클릭 이벤트가 있어도 1초에 한번씩만 data.clientY를 콘솔에
// 찍히게 해준다. 유용한 메소드가 많은듯

 

RxJS 이해해야 할 부분들: Observable, Observer, Subscriptions

"Observable is a wrapper around some data source."라고 유튜브에서 설명한다.

여기서 data source는 일반적으로 stream of values (데이터 흐름)이라고 보면 된다.

여기서 중요한 부분은 observable은 꼭 asynchronous(비동기) 데이터에서만 사용되는 개념은 아니다. 

Observable은 이 데이터의 흐름을 감싸고 있는 개념이라고 보면 된다.

 

Stream of values(데이터 흐름)/비동기 or 동기 데이터에서 (새로운 데이터가 생기거나/이벤트가 일어나거나)/ 에러가 생기거나/ 이벤트가 끝났을 때 이런 일이 있다고 말/행동하는 애가 있는데 그것을 Observer가 한다.

내가 이해했을 때는 영어 뜻 그래로 Observer: 뭔가 관할하는 놈이라는 것.

비동기/동기 데이터가 있는데 새로운 데이터가 들어온다면 Observer가 대기 타다가 데이터 들어왔음 하고 말해주는 역할을 하는 것.

 

Observable이랑 observer를 연결해줘야 하는데 그것을 subscription이라는 애가 하는 것.

 

Observer는 3개의 method를 실행하는데 next(), error(), complete()가 있다.

next()는 새로운 value가 들어왔을 때 실행되고,  error()를 에러가 났을 때, complete()는 더 이상 새로운 데이터가 들어오지 않을 떄 실행된다. 

 

# 버튼을 클릭했을 때 클릭이벤트의 clientX값을 출력한다.
Rx.Observable.fromEvent(button,'click')
	.subscribe((value) => console.log(value.clientX));
    
# .subscribe() 메소드에서 Observable를 넘긴다. value라고 써있어서 헷갈릴 수도 있지만 
# .subscribe메소드는 아래와 같이 쓸 수 있다.

# 위에 첫번때 옵져버는 error, complete가 생략됐었던것.
Rx.Observable.fromEvent(button,'click')
	.subscribe((value) => {console.log(value.clientX)},
    		   (error) => { ... },
               () => {...});
            
# 아니면 이렇게 observer를 만들어서 넘길 수도 있다. object로 만들어서!                       
var observer = {
  next: (value) => {
    console.log(value)
  },
  error: (error) => {
    console.log(value)
  },
  complete: () => {
    console.info('completed')
  }
}     
     
Rx.Observable.fromEvent(button,'click')
	.subscribe(observer);
 

 

var observer = {
  next: (value) => {
    console.log(value)
  },
  error: (error) => {
    console.log(value)
  },
  complete: () => {
    console.info('completed')
  }
}   


# 이렇게 옵져버를 처음부터 만들 수도 있음.
Rx.Observable.create(function(oobs){
	obs.next('A value');
}).subscribe(observer);


# 이렇게 하면 Second value는 출력되지 않는데. 에러가 난다면 이 흐름은 끊기기 떄문이다.
Rx.Observable.create(function(oobs){
	obs.next('A value');
    obs.error('Error');
    obs.next('Second value');
}).subscribe(observer);


# 이렇게 쓰면 One, Two를 실행하고 complete를 한다.
Rx.Observable.create(function(obs){
  obs.next('One');
  setTimeout(() => {
    obs.complete()
  }, 2000)
  obs.next('Two')
}).subscribe(observer);
# 이렇게 쓰는 것
Rx.Observable.create(function(obs) {
	button.onclick = function(event) {
	obs.next(event)}})
    .subscribe(observer)

 

 

 

Subscription must be unsubscribed!!

여기서 중요한 부분이 또 나온다. Observable을 생생하고 subscribe를 하면 메로리가 낭비된다. Observer는 계속 새로운 데이터가 들어오나 ~ 계속 기다리고 있기 때문이다.

# 이렇게 변수에 넣고 observable을 관리한다.
var subscription = Rx.Observable.create(function(obs) {
                    button.onclick = function(event) {
  					obs.next(event)}}).subscribe(observer)


# 5초 후에 subscription을 구독을 끝낸다. 그러면 5초 후에는 버튼을 클릭하더라고 데이터를 출력하지 않는다.
setTimeout( () => {
  subscription.unsubscribe()
}, 5000)