SlideShare a Scribd company logo
1 of 46
Download to read offline
RxJava in
Scott
Joonhyeok Im
for RxJava
Why RxJava?
http://news20.busan.com/controller/newsController.jsp?
newsId=20170123000265
http://clien.net/cs2/bbs/board.php?bo_table=park&wr_id=53708884
2003 2017
An API for asynchronous programming
with observable streams
Reactive Extensions
a.k.a. ReactiveX
시작할까요? (y)
이미지 http://www.mediamolecule.com/blog/article/game_guide_go_go
asynchronous
observable
streams
비동기
asynchronous
동기
synchronous
“내가 지금 바쁘니까 있다가 줄께.”
요청과 결과가 동시에 일어나지 않음
“조금만 기다려. 되면 얼른 줄께.”
요청과 결과가 동시에 일어남
설계가 간단하고 직관적임 설계가 복잡함
결과가 주어질 때까지
아무것도 못하고 대기
아무리 길어져도 다른 작업을 할 수 있음
효율적인 자원관리가 가능
무거운 데이터 처리, 네트워크 I/O간단한 처리, 화면 처리
blocking non-blocking
심화 https://slipp.net/questions/367
asynchronous
observable
streams
이미지/참고 https://medium.com/@elliscmarte/introducing-reactive-programming-rx-js-fc7151a69508
Event Iterable
(pull)
Observable
(push)
Retrieve data T next() onNext(T)
Discover error throws Exception onError(Exception)
Complete !hasNext() onCompleted()
Single thread Single/Multi thread
Synchronous Asynchronous
asynchronous
observable
streams
http://www.northstandchat.com/showthread.php?325439-Stream
$ pbpaste | highlight --syntax=java -O rtf --style molokai | pbcopy
InputStream fin = new FileInputStream("1209027132159_1.jpg");
OutputStream fos = new FileOutputStream("copy.jpg");
while(true) {
int data = fin.read();
if(data == -1) {
System.out.println("EOF");
break;
}
fos.write(data);
}
fin.close();
fos.close();
C:> type autoexec.bat | more
그럼 이제 만들어봅시다!
이미지 http://mattswowguide.weebly.com/03-character-creation.html
Create Observable
Transform
Subscribe
Observable.create({
…
})
Create
Observable.just("only item")
Just From
fromIterable, fromArray
List<String> list;
Observable.fromIterable(list)
EditText editText;
RxTextView.textChanges(editText)
Create Observable
Transform
Subscribe
Map Filter
FlatMap
Observable<List<String>> getTagRelations;
tagsObservable
.flatMap(tag -> getTagRelations(tag))
생성
Create — 직접적인 코드 구현을 통해 옵저버 메서드를 호출하여 Observable을 생성한다
Defer — 옵저버가 구독하기 전까지는 Observable 생성을 지연하고 구독이 시작되면 옵저버 별
로 새로운 Observable을 생성한다
Empty/Never/Throw — 아주 정확하고 제한된 행동을 하는 Observable을 생성한다
From — 다른 객체나 자료 구조를 Observable로 변환한다
Interval — 특정 시간별로 연속된 정수형을 배출하는 Observable을 생성한다
Just — 객체 하나 또는 객채집합을 Observable로 변환한다. 변환된 Observable은 원본 객체
들을 발행한다
Range — 연속된 범위(Range)의 정수를 발행하는 Observable을 생성한다
Repeat — 특정 항목이나 연속된 항목들을 반복적으로 배출하는 Observable을 생성한다
Start — 함수의 실행 결과를 배출하는 Observable을 생성한다
Timer — 지정된 시간이 지나고 난 후 항목을 하나 배출하는 Observable을 생성한다
변환
Buffer — Observable로부터 정기적으로 항목들을 수집하고 묶음으로 만든 후에 묶음 안에 있는 항
목들을 한번에 하나씩 배출하지 않고 수집된 묶음 단위로 배출한다
FlatMap — 하나의 Observable이 발행하는 항목들을 여러개의 Observable로 변환하고, 항목들
의 배출을 차례차례 줄 세워 하나의 Observable로 전달한다
GroupBy — 원본 Observable이 배출하는 항목들을 키(Key) 별로 묶은 후 Observable에 담는
다. 이렇게 키 별로 만들어진 Observable들은 자기가 담고 있는 묶음의 항목들을 배출한다
Map — Observable이 배출한 항목에 함수를 적용한다
Scan — Observable이 배출한 항목에 연속적으로 함수를 적용하고 실행한 후 성공적으로 실행된
함수의 리턴 값을 발행한다
Window — 정기적으로 Observable의 항목들을 더 작은 단위의 Observable 윈도우로 나눈 후에,
한번에 하나씩 항목들을 발행하는 대신 작게 나눠진 윈도우 단위로 항목들을 배출한다
필터링
Debounce — Observable의 시간 흐름이 지속되는 상태에서 다른 항목들은 배출하지 않고
특정 시간 마다 그 시점에 존재하는 항목 하나를 Observable로부터 배출한다
Distinct — Observable이 배출하는 항목들 중 중복을 제거한 항목들을 배출한다
ElementAt — Obserable에서 n번째 항목만 배출한다
Filter — 테스트 조건을 만족하는 항목들만 배출한다
First — 맨 첫 번째 항목 또는 조건을 만족하는 첫 번째 항목만 배출한다
IgnoreElements — 항목들을 배출하지는 않고 종료 알림은 보낸다
Last — Observable의 마지막 항목만 배출한다
Sample — 특정 시간 간격으로 최근에 Observable이 배출한 항목들을 배출한다
Skip — Observable이 배출한 처음 n개의 항목들을 숨긴다
SkipLast — Observable이 배출한 마지막 n개의 항목들을 숨긴다
Take — Observable이 배츨한 처음 n개의 항목들만 배출한다
TakeLast — Observable이 배출한 마지막 n개의 항목들만 배출한다
결합
And/Then/When — 두 개 이상의 Observable들이 배출한 항목들을 'Pattern'과 'Plan' 중계자를 이용
해서 결합한다
CombineLatest — 두 개의 Observable 중 하나가 항목을 배출할 때 배출된 마지막 항목과 다른 한
Observable이 배출한 항목을 결합한 후 함수를 적용하여 실행 후 실행된 결과를 배출한다
Join — A Observable과 B Observable이 배출한 항목들을 결합하는데, 이때 B Observable은 배출
한 항목이 타임 윈도우를 가지고 있고 이 타임 윈도우가 열린 동안 A Observable은 항목의 배출을 계속
한다. Join 연산자는 B Observable의 항목을 배출하고 배출된 항목은 타임 윈도우를 시작시킨다. 타임
윈도우가 열려 있는 동안 A Observable은 자신의 항목들을 계속 배출하여 이 두 항목들을 결합한다
Merge — 복수 개의 Observable들이 배출하는 항목들을 머지시켜 하나의 Observable로 만든다
StartWith — 소스 Observable이 항목을 배출하기 전에 다른 항목들을 앞에 추가한 후 배출한다
Switch — Observable들을 배출하는 Observable을 싱글 Observable로 변환하다. 변환된 싱글
Observable은 변환 전 소스 Observable들이 배출한 항목들을 배출한다
Zip — 명시한 함수를 통해 여러 Observable들이 배출한 항목들을 결합하고 함수의 실행 결과를 배출한
다
오류 처리 연산자, Observable 유틸리티 연산자, 조건과 불린 연산자(Boolean), 수학과 집계 연산자, 역압(Backpressure) 연산자, ...
http://reactivex.io/documentation/ko/operators.html
Create Observable
Transform
Subscribe
onNext(T t)
onError(Throwable e)
onCompleted()
onSubscribe
진짜로 시작하기
이미지 https://i.ytimg.com/vi/oLy8hMW-e48/maxresdefault.jpg
경고
지금부터 나오는 소스코드는 완벽한 것이 아니므로,
부족한 부분은 스스로 잘 고쳐서 안정적인 프로그래밍을 부탁드리며,
아울러 발표자에게도 한 수 가르쳐주시길 😀
Icon Author: http://www.flaticon.com/authors/gregor-cresnar
시나리오1. 키워드를 넣으면 서버 API를 통해
연관 검색어를 동적으로 보여주기
TextView에 OnTextChangedListener를 달고,
입력된 텍스트로 HTTP 클라이언트를 통해
Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
@OnTextChanged(R.id.keyword)
public void keywordChanged() {
}
RxTextView.textChanges(R.id.keyword);
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다.
public interface MyRestService {
@GET("suggest/{keyword}")
Call<List<String>> listSuggestions(
@Path("keyword") String keyword);
}
@OnTextChanged(R.id.keyword)
public void keywordChanged(String keyword) {
Call<List<String>> suggestions =
service.listSuggestions(keyword);
}
public interface MyRestService {
@GET("suggest/{keyword}")
Observable<List<String>> listSuggestions(
@Path("keyword") String keyword);
}
RxTextView.textChanges(R.id.keyword)
.map(CharSequence::toString)
.flatMap(text -> service.listSuggestions(text));
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
public interface MyRestService {
@GET("suggest/{keyword}")
Call<List<String>> listSuggestions(
@Path("keyword") String keyword);
}
@OnTextChanged(R.id.keyword)
public void keywordChanged(String keyword) {
Call<List<String>> suggestions =
service.listSuggestions(keyword);
suggestions.enqueue(new Callback<List<String>>() {
@Override
public void onResponse(Call<List<String>> call,
Response<List<String>> response) {
List<String> texts = response.body();
for (String t : texts) {
adapter.add(t);
}
}
@Override
public void onFailure(Call<List<String>> call,
Throwable t) {
}
});
}
public interface MyRestService {
@GET("suggest/{keyword}")
Observable<List<String>> listSuggestions(
@Path("keyword") String keyword);
}
RxTextView.textChanges(R.id.keyword)
.map(CharSequence::toString)
.flatMap(text -> service.listSuggestions(text))
.flatMapIterable(texts -> texts)
.subscribe(adapter::add);
뭔가 어색해조금 더 사용자에게 친화적이면 좋겠어
버전 올라가는 소리가 들려
키워드 입력하는 시점에 왜 이전 키워드에 대한 리스트를 잠깐 보여주지?
이게 되는 건가? 안 되는 건가?
에러 나는데 제가 뭘 잘못한건가요?
약간 좀 느린 느낌인데 더 빠르게 안되나요?
TextView에 OnTextChangedListener를 달고,
입력된 텍스트로 HTTP 클라이언트를 통해
Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
RecyclerView의 Adapter의 데이터를 비워준다.
끝나면 ProgressBar를 숨긴다.
ProgressBar를 보여준다.
하다가 뭔가 문제가 생기면 사용자한테 친절하게 알려준다. SnackBar를 보여주자.
TextView에 텍스트가 없거나 스페이스만 있을 때는 네트워크까지 가지 말자.
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
시작하기 전에 Adapter에 데이터를 지운다.
입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
@OnTextChanged(R.id.keyword)
public void keywordChanged(String keyword) {
adapter.clear();
Call<List<String>> suggestions =
service.listSuggestions(keyword);
suggestions.enqueue(new Callback<List<String>>() {
@Override
public void onResponse(Call<List<String>> call,
Response<List<String>> response) {
List<String> texts = response.body();
for (String t : texts) {
adapter.add(t);
}
}
@Override
public void onFailure(Call<List<String>> call,
Throwable t) {
}
});
}
RxTextView.textChanges(R.id.keyword)
.map(CharSequence::toString)
.flatMap(text -> service.listSuggestions(text))
.flatMapIterable(texts -> texts)
.subscribe(adapter::add,
e -> {},
() -> {},
__ -> adapter.clear());
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
시작하기 전에 Adapter에 데이터를 지우고 프로그레스바를 보여준다.
입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
끝나면 프로그레스바를 숨긴다.
@OnTextChanged(R.id.keyword)
public void keywordChanged(String keyword) {
adapter.clear();
progressBar.setVisibility(VISIBLE);
Call<List<String>> suggestions =
service.listSuggestions(keyword);
suggestions.enqueue(new Callback<List<String>>() {
@Override
public void onResponse(Call<List<String>> call,
Response<List<String>> response) {
List<String> texts = response.body();
for (String t : texts) {
adapter.add(t);
}
progressBar.setVisibility(GONE);
}
@Override
public void onFailure(Call<List<String>> call,
Throwable t) {
}
});
}
RxTextView.textChanges(R.id.keyword)
.map(CharSequence::toString)
.flatMap(text -> service.listSuggestions(text))
.flatMapIterable(texts -> texts)
.subscribe(adapter::add,
e -> {},
() -> progressBar.setVisibility(GONE),
__ -> {
adapter.clear();
progressBar.setVisibility(VISIBLE);
});
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
시작하기 전에 Adapter에 데이터를 지우고 프로그레스바를 보여준다.
입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
끝나면 프로그레스바를 숨긴다.
에러가 발생하면 스낵바를 보여준다.
@OnTextChanged(R.id.keyword)
public void keywordChanged(String keyword) {
adapter.clear();
progressBar.setVisibility(VISIBLE);
Call<List<String>> suggestions =
service.listSuggestions(keyword);
suggestions.enqueue(new Callback<List<String>>() {
@Override
public void onResponse(Call<List<String>> call,
Response<List<String>> response) {
List<String> texts = response.body();
for (String t : texts) {
adapter.add(t);
}
progressBar.setVisibility(GONE);
}
@Override
public void onFailure(Call<List<String>> call,
Throwable t) {
SnackBar.make(view, "Something wrong!", LENGTH_LONG).show();
Log.d(TAG, "Error on keywordChanged.", t);
}
});
}
RxTextView.textChanges(R.id.keyword)
.map(CharSequence::toString)
.flatMap(text -> service.listSuggestions(text))
.flatMapIterable(texts -> texts)
.subscribe(adapter::add,
e -> {
SnackBar.make(view, "Something wrong!", LENGTH_LONG).show();
Log.d(TAG, "Error on keywordChanged.", e);
}, () -> progressBar.setVisibility(GONE),
__ -> {
adapter.clear();
progressBar.setVisibility(VISIBLE);
});
without Rx with Rx
TextView에 OnTextChangedListener를 달고,
입력된 키워드가 유효한지 체크한다.
시작하기 전에 Adapter에 데이터를 지우고 프로그레스바를 보여준다.
입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다.
받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
끝나면 프로그레스바를 숨긴다.
에러가 발생하면 스낵바를 보여준다.
@OnTextChanged(R.id.keyword)
public void keywordChanged(String keyword) {
if(““.equals(keyword.trim())
return;
adapter.clear();
progressBar.setVisibility(VISIBLE);
Call<List<String>> suggestions =
service.listSuggestions(keyword);
suggestions.enqueue(new Callback<List<String>>() {
@Override
public void onResponse(Call<List<String>> call,
Response<List<String>> response) {
List<String> texts = response.body();
for (String t : texts) {
adapter.add(t);
}
progressBar.setVisibility(GONE);
}
@Override
public void onFailure(Call<List<String>> call,
Throwable t) {
SnackBar.make(view, "Something wrong!", LENGTH_LONG).show();
Log.d(TAG, "Error on keywordChanged.", t);
}
});
}
RxTextView.textChanges(R.id.keyword)
.map(CharSequence::toString)
.map(String::trim)
.filter(t -> !"".equals(t))
.flatMap(text -> service.listSuggestions(text))
.flatMapIterable(texts -> texts)
.subscribe(adapter::add,
e -> {
SnackBar.make(view, "Something wrong!", LENGTH_LONG).show();
Log.d(TAG, "Error on keywordChanged.", e);
}, () -> progressBar.setVisibility(GONE),
__ -> {
adapter.clear();
progressBar.setVisibility(VISIBLE);
});
RxJava로 짠 코드
테스트 할 수 있나요? (yn)
yes, but think of the thread
Congratulations!
Level 2
• Hot/Cold Observable
• more APIs of RxJava
• Test for each onNext
Next
Quests
http://wowguidessource.com/5-wow-leveling-tips-to-acquire-world-of-warcraft-level-85-fast.php
• Future<T>, Single<T>
Reference
• ReactiveX 공식 사이트 http://reactivex.io/
• GDG 2014 - RxJava를 활용한 Functional Reactive
Programming https://www.slideshare.net/waynejo/gdg-41029986
• 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기 https://
www.slideshare.net/jeokrang/rx-70197043
• 동기와 비동기, 블로킹과 논블로킹 http://nsinc.tistory.com/108
• http://nsinc.tistory.com/108
thx
EOP

More Related Content

Viewers also liked

Funciones mentales superiores
Funciones mentales superioresFunciones mentales superiores
Funciones mentales superioresCarolina
 
EL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADA
EL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADAEL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADA
EL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADAMarinalen1
 
Bab 5 (ukuran letak dan penyebaran)
Bab 5 (ukuran letak dan penyebaran)Bab 5 (ukuran letak dan penyebaran)
Bab 5 (ukuran letak dan penyebaran)fatria anggita
 
Campos de acción de las tic
Campos de acción de las ticCampos de acción de las tic
Campos de acción de las ticnatalia rozo
 

Viewers also liked (7)

Funciones mentales superiores
Funciones mentales superioresFunciones mentales superiores
Funciones mentales superiores
 
EL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADA
EL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADAEL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADA
EL FLORECIMIENTO DEL ÁRBOL SAGRADO Y EL SIGNIFICADO DE LA PIPA SAGRADA
 
Syllabus 2017
Syllabus 2017Syllabus 2017
Syllabus 2017
 
Validadores sistemas (1)
Validadores sistemas (1)Validadores sistemas (1)
Validadores sistemas (1)
 
Bab 5 (ukuran letak dan penyebaran)
Bab 5 (ukuran letak dan penyebaran)Bab 5 (ukuran letak dan penyebaran)
Bab 5 (ukuran letak dan penyebaran)
 
El fútbol
El fútbolEl fútbol
El fútbol
 
Campos de acción de las tic
Campos de acción de las ticCampos de acción de las tic
Campos de acción de las tic
 

Similar to RxJava in Looky

Netty 세미나
Netty 세미나Netty 세미나
Netty 세미나Jang Hoon
 
[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화
[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화
[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화InfraEngineer
 
[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)
[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)
[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)CONNECT FOUNDATION
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJSEunYoung Kim
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현NAVER Engineering
 
Reactive Programming with Rxjs
Reactive Programming with RxjsReactive Programming with Rxjs
Reactive Programming with RxjsSangHun Lee
 
Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.장현 한
 
RxJS로 비동기와 친해지기
RxJS로 비동기와 친해지기RxJS로 비동기와 친해지기
RxJS로 비동기와 친해지기Seokju Na
 
React를 이용하여 멀티플랫폼에서 개발하기
React를 이용하여 멀티플랫폼에서 개발하기React를 이용하여 멀티플랫폼에서 개발하기
React를 이용하여 멀티플랫폼에서 개발하기WebFrameworks
 
React 실무활용 이야기
React 실무활용 이야기React 실무활용 이야기
React 실무활용 이야기철민 배
 
쇼핑검색 React 전환 경험 공유
쇼핑검색 React 전환 경험 공유쇼핑검색 React 전환 경험 공유
쇼핑검색 React 전환 경험 공유NAVER SHOPPING
 
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경YoungSu Son
 
React, Redux 실전 적용기
React, Redux 실전 적용기React, Redux 실전 적용기
React, Redux 실전 적용기은미 김
 
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XpressEngine
 

Similar to RxJava in Looky (20)

Netty 세미나
Netty 세미나Netty 세미나
Netty 세미나
 
[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화
[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화
[MeetUp][3rd] Prometheus 와 함께하는 모니터링 및 시각화
 
[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)
[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)
[부스트캠프 Tech Talk]손정현_PUB/SUB를 적용한 Todo앱 만들기(순한맛)
 
Data-binding AngularJS
Data-binding AngularJSData-binding AngularJS
Data-binding AngularJS
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
 
Reactive Programming with Rxjs
Reactive Programming with RxjsReactive Programming with Rxjs
Reactive Programming with Rxjs
 
Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.Angular는 사실 어렵지 않습니다.
Angular는 사실 어렵지 않습니다.
 
RxJS로 비동기와 친해지기
RxJS로 비동기와 친해지기RxJS로 비동기와 친해지기
RxJS로 비동기와 친해지기
 
React를 이용하여 멀티플랫폼에서 개발하기
React를 이용하여 멀티플랫폼에서 개발하기React를 이용하여 멀티플랫폼에서 개발하기
React를 이용하여 멀티플랫폼에서 개발하기
 
Flux 예제 분석 2
Flux 예제 분석 2Flux 예제 분석 2
Flux 예제 분석 2
 
React 실무활용 이야기
React 실무활용 이야기React 실무활용 이야기
React 실무활용 이야기
 
12books
12books12books
12books
 
Showroom 2019-react
Showroom 2019-reactShowroom 2019-react
Showroom 2019-react
 
쇼핑검색 React 전환 경험 공유
쇼핑검색 React 전환 경험 공유쇼핑검색 React 전환 경험 공유
쇼핑검색 React 전환 경험 공유
 
Spring boot DI
Spring boot DISpring boot DI
Spring boot DI
 
Springmvc
SpringmvcSpringmvc
Springmvc
 
Light Tutorial Django
Light Tutorial DjangoLight Tutorial Django
Light Tutorial Django
 
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
[NEXT] 화면 재갱신이 되는 안드로이드 앱 만들기 - 네트워크에 독립하는 구조로 변경
 
React, Redux 실전 적용기
React, Redux 실전 적용기React, Redux 실전 적용기
React, Redux 실전 적용기
 
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
XECon2015 :: [2-2] 박상현 - React로 개발하는 SPA 실무 이야기
 

RxJava in Looky

  • 4.
  • 5.
  • 6.
  • 7. An API for asynchronous programming with observable streams Reactive Extensions a.k.a. ReactiveX
  • 11. 비동기 asynchronous 동기 synchronous “내가 지금 바쁘니까 있다가 줄께.” 요청과 결과가 동시에 일어나지 않음 “조금만 기다려. 되면 얼른 줄께.” 요청과 결과가 동시에 일어남 설계가 간단하고 직관적임 설계가 복잡함 결과가 주어질 때까지 아무것도 못하고 대기 아무리 길어져도 다른 작업을 할 수 있음 효율적인 자원관리가 가능 무거운 데이터 처리, 네트워크 I/O간단한 처리, 화면 처리 blocking non-blocking 심화 https://slipp.net/questions/367
  • 14. Event Iterable (pull) Observable (push) Retrieve data T next() onNext(T) Discover error throws Exception onError(Exception) Complete !hasNext() onCompleted() Single thread Single/Multi thread Synchronous Asynchronous
  • 17. $ pbpaste | highlight --syntax=java -O rtf --style molokai | pbcopy InputStream fin = new FileInputStream("1209027132159_1.jpg"); OutputStream fos = new FileOutputStream("copy.jpg"); while(true) { int data = fin.read(); if(data == -1) { System.out.println("EOF"); break; } fos.write(data); } fin.close(); fos.close(); C:> type autoexec.bat | more
  • 18. 그럼 이제 만들어봅시다! 이미지 http://mattswowguide.weebly.com/03-character-creation.html
  • 21. Observable.just("only item") Just From fromIterable, fromArray List<String> list; Observable.fromIterable(list)
  • 24.
  • 27. 생성 Create — 직접적인 코드 구현을 통해 옵저버 메서드를 호출하여 Observable을 생성한다 Defer — 옵저버가 구독하기 전까지는 Observable 생성을 지연하고 구독이 시작되면 옵저버 별 로 새로운 Observable을 생성한다 Empty/Never/Throw — 아주 정확하고 제한된 행동을 하는 Observable을 생성한다 From — 다른 객체나 자료 구조를 Observable로 변환한다 Interval — 특정 시간별로 연속된 정수형을 배출하는 Observable을 생성한다 Just — 객체 하나 또는 객채집합을 Observable로 변환한다. 변환된 Observable은 원본 객체 들을 발행한다 Range — 연속된 범위(Range)의 정수를 발행하는 Observable을 생성한다 Repeat — 특정 항목이나 연속된 항목들을 반복적으로 배출하는 Observable을 생성한다 Start — 함수의 실행 결과를 배출하는 Observable을 생성한다 Timer — 지정된 시간이 지나고 난 후 항목을 하나 배출하는 Observable을 생성한다 변환 Buffer — Observable로부터 정기적으로 항목들을 수집하고 묶음으로 만든 후에 묶음 안에 있는 항 목들을 한번에 하나씩 배출하지 않고 수집된 묶음 단위로 배출한다 FlatMap — 하나의 Observable이 발행하는 항목들을 여러개의 Observable로 변환하고, 항목들 의 배출을 차례차례 줄 세워 하나의 Observable로 전달한다 GroupBy — 원본 Observable이 배출하는 항목들을 키(Key) 별로 묶은 후 Observable에 담는 다. 이렇게 키 별로 만들어진 Observable들은 자기가 담고 있는 묶음의 항목들을 배출한다 Map — Observable이 배출한 항목에 함수를 적용한다 Scan — Observable이 배출한 항목에 연속적으로 함수를 적용하고 실행한 후 성공적으로 실행된 함수의 리턴 값을 발행한다 Window — 정기적으로 Observable의 항목들을 더 작은 단위의 Observable 윈도우로 나눈 후에, 한번에 하나씩 항목들을 발행하는 대신 작게 나눠진 윈도우 단위로 항목들을 배출한다 필터링 Debounce — Observable의 시간 흐름이 지속되는 상태에서 다른 항목들은 배출하지 않고 특정 시간 마다 그 시점에 존재하는 항목 하나를 Observable로부터 배출한다 Distinct — Observable이 배출하는 항목들 중 중복을 제거한 항목들을 배출한다 ElementAt — Obserable에서 n번째 항목만 배출한다 Filter — 테스트 조건을 만족하는 항목들만 배출한다 First — 맨 첫 번째 항목 또는 조건을 만족하는 첫 번째 항목만 배출한다 IgnoreElements — 항목들을 배출하지는 않고 종료 알림은 보낸다 Last — Observable의 마지막 항목만 배출한다 Sample — 특정 시간 간격으로 최근에 Observable이 배출한 항목들을 배출한다 Skip — Observable이 배출한 처음 n개의 항목들을 숨긴다 SkipLast — Observable이 배출한 마지막 n개의 항목들을 숨긴다 Take — Observable이 배츨한 처음 n개의 항목들만 배출한다 TakeLast — Observable이 배출한 마지막 n개의 항목들만 배출한다 결합 And/Then/When — 두 개 이상의 Observable들이 배출한 항목들을 'Pattern'과 'Plan' 중계자를 이용 해서 결합한다 CombineLatest — 두 개의 Observable 중 하나가 항목을 배출할 때 배출된 마지막 항목과 다른 한 Observable이 배출한 항목을 결합한 후 함수를 적용하여 실행 후 실행된 결과를 배출한다 Join — A Observable과 B Observable이 배출한 항목들을 결합하는데, 이때 B Observable은 배출 한 항목이 타임 윈도우를 가지고 있고 이 타임 윈도우가 열린 동안 A Observable은 항목의 배출을 계속 한다. Join 연산자는 B Observable의 항목을 배출하고 배출된 항목은 타임 윈도우를 시작시킨다. 타임 윈도우가 열려 있는 동안 A Observable은 자신의 항목들을 계속 배출하여 이 두 항목들을 결합한다 Merge — 복수 개의 Observable들이 배출하는 항목들을 머지시켜 하나의 Observable로 만든다 StartWith — 소스 Observable이 항목을 배출하기 전에 다른 항목들을 앞에 추가한 후 배출한다 Switch — Observable들을 배출하는 Observable을 싱글 Observable로 변환하다. 변환된 싱글 Observable은 변환 전 소스 Observable들이 배출한 항목들을 배출한다 Zip — 명시한 함수를 통해 여러 Observable들이 배출한 항목들을 결합하고 함수의 실행 결과를 배출한 다 오류 처리 연산자, Observable 유틸리티 연산자, 조건과 불린 연산자(Boolean), 수학과 집계 연산자, 역압(Backpressure) 연산자, ... http://reactivex.io/documentation/ko/operators.html
  • 31. 경고 지금부터 나오는 소스코드는 완벽한 것이 아니므로, 부족한 부분은 스스로 잘 고쳐서 안정적인 프로그래밍을 부탁드리며, 아울러 발표자에게도 한 수 가르쳐주시길 😀 Icon Author: http://www.flaticon.com/authors/gregor-cresnar
  • 32. 시나리오1. 키워드를 넣으면 서버 API를 통해 연관 검색어를 동적으로 보여주기
  • 33. TextView에 OnTextChangedListener를 달고, 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다.
  • 34. @OnTextChanged(R.id.keyword) public void keywordChanged() { } RxTextView.textChanges(R.id.keyword); without Rx with Rx TextView에 OnTextChangedListener를 달고,
  • 35. without Rx with Rx TextView에 OnTextChangedListener를 달고, 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. public interface MyRestService { @GET("suggest/{keyword}") Call<List<String>> listSuggestions( @Path("keyword") String keyword); } @OnTextChanged(R.id.keyword) public void keywordChanged(String keyword) { Call<List<String>> suggestions = service.listSuggestions(keyword); } public interface MyRestService { @GET("suggest/{keyword}") Observable<List<String>> listSuggestions( @Path("keyword") String keyword); } RxTextView.textChanges(R.id.keyword) .map(CharSequence::toString) .flatMap(text -> service.listSuggestions(text));
  • 36. without Rx with Rx TextView에 OnTextChangedListener를 달고, 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다. public interface MyRestService { @GET("suggest/{keyword}") Call<List<String>> listSuggestions( @Path("keyword") String keyword); } @OnTextChanged(R.id.keyword) public void keywordChanged(String keyword) { Call<List<String>> suggestions = service.listSuggestions(keyword); suggestions.enqueue(new Callback<List<String>>() { @Override public void onResponse(Call<List<String>> call, Response<List<String>> response) { List<String> texts = response.body(); for (String t : texts) { adapter.add(t); } } @Override public void onFailure(Call<List<String>> call, Throwable t) { } }); } public interface MyRestService { @GET("suggest/{keyword}") Observable<List<String>> listSuggestions( @Path("keyword") String keyword); } RxTextView.textChanges(R.id.keyword) .map(CharSequence::toString) .flatMap(text -> service.listSuggestions(text)) .flatMapIterable(texts -> texts) .subscribe(adapter::add);
  • 37. 뭔가 어색해조금 더 사용자에게 친화적이면 좋겠어 버전 올라가는 소리가 들려 키워드 입력하는 시점에 왜 이전 키워드에 대한 리스트를 잠깐 보여주지? 이게 되는 건가? 안 되는 건가? 에러 나는데 제가 뭘 잘못한건가요? 약간 좀 느린 느낌인데 더 빠르게 안되나요?
  • 38. TextView에 OnTextChangedListener를 달고, 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다. RecyclerView의 Adapter의 데이터를 비워준다. 끝나면 ProgressBar를 숨긴다. ProgressBar를 보여준다. 하다가 뭔가 문제가 생기면 사용자한테 친절하게 알려준다. SnackBar를 보여주자. TextView에 텍스트가 없거나 스페이스만 있을 때는 네트워크까지 가지 말자.
  • 39. without Rx with Rx TextView에 OnTextChangedListener를 달고, 시작하기 전에 Adapter에 데이터를 지운다. 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다. @OnTextChanged(R.id.keyword) public void keywordChanged(String keyword) { adapter.clear(); Call<List<String>> suggestions = service.listSuggestions(keyword); suggestions.enqueue(new Callback<List<String>>() { @Override public void onResponse(Call<List<String>> call, Response<List<String>> response) { List<String> texts = response.body(); for (String t : texts) { adapter.add(t); } } @Override public void onFailure(Call<List<String>> call, Throwable t) { } }); } RxTextView.textChanges(R.id.keyword) .map(CharSequence::toString) .flatMap(text -> service.listSuggestions(text)) .flatMapIterable(texts -> texts) .subscribe(adapter::add, e -> {}, () -> {}, __ -> adapter.clear());
  • 40. without Rx with Rx TextView에 OnTextChangedListener를 달고, 시작하기 전에 Adapter에 데이터를 지우고 프로그레스바를 보여준다. 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다. 끝나면 프로그레스바를 숨긴다. @OnTextChanged(R.id.keyword) public void keywordChanged(String keyword) { adapter.clear(); progressBar.setVisibility(VISIBLE); Call<List<String>> suggestions = service.listSuggestions(keyword); suggestions.enqueue(new Callback<List<String>>() { @Override public void onResponse(Call<List<String>> call, Response<List<String>> response) { List<String> texts = response.body(); for (String t : texts) { adapter.add(t); } progressBar.setVisibility(GONE); } @Override public void onFailure(Call<List<String>> call, Throwable t) { } }); } RxTextView.textChanges(R.id.keyword) .map(CharSequence::toString) .flatMap(text -> service.listSuggestions(text)) .flatMapIterable(texts -> texts) .subscribe(adapter::add, e -> {}, () -> progressBar.setVisibility(GONE), __ -> { adapter.clear(); progressBar.setVisibility(VISIBLE); });
  • 41. without Rx with Rx TextView에 OnTextChangedListener를 달고, 시작하기 전에 Adapter에 데이터를 지우고 프로그레스바를 보여준다. 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다. 끝나면 프로그레스바를 숨긴다. 에러가 발생하면 스낵바를 보여준다. @OnTextChanged(R.id.keyword) public void keywordChanged(String keyword) { adapter.clear(); progressBar.setVisibility(VISIBLE); Call<List<String>> suggestions = service.listSuggestions(keyword); suggestions.enqueue(new Callback<List<String>>() { @Override public void onResponse(Call<List<String>> call, Response<List<String>> response) { List<String> texts = response.body(); for (String t : texts) { adapter.add(t); } progressBar.setVisibility(GONE); } @Override public void onFailure(Call<List<String>> call, Throwable t) { SnackBar.make(view, "Something wrong!", LENGTH_LONG).show(); Log.d(TAG, "Error on keywordChanged.", t); } }); } RxTextView.textChanges(R.id.keyword) .map(CharSequence::toString) .flatMap(text -> service.listSuggestions(text)) .flatMapIterable(texts -> texts) .subscribe(adapter::add, e -> { SnackBar.make(view, "Something wrong!", LENGTH_LONG).show(); Log.d(TAG, "Error on keywordChanged.", e); }, () -> progressBar.setVisibility(GONE), __ -> { adapter.clear(); progressBar.setVisibility(VISIBLE); });
  • 42. without Rx with Rx TextView에 OnTextChangedListener를 달고, 입력된 키워드가 유효한지 체크한다. 시작하기 전에 Adapter에 데이터를 지우고 프로그레스바를 보여준다. 입력된 텍스트로 HTTP 클라이언트를 통해 Suggestion 텍스트 리스트를 받아온다. 받아온 리스트를 밑에 있는 RecyclerView의 Adapter에 반영한다. 끝나면 프로그레스바를 숨긴다. 에러가 발생하면 스낵바를 보여준다. @OnTextChanged(R.id.keyword) public void keywordChanged(String keyword) { if(““.equals(keyword.trim()) return; adapter.clear(); progressBar.setVisibility(VISIBLE); Call<List<String>> suggestions = service.listSuggestions(keyword); suggestions.enqueue(new Callback<List<String>>() { @Override public void onResponse(Call<List<String>> call, Response<List<String>> response) { List<String> texts = response.body(); for (String t : texts) { adapter.add(t); } progressBar.setVisibility(GONE); } @Override public void onFailure(Call<List<String>> call, Throwable t) { SnackBar.make(view, "Something wrong!", LENGTH_LONG).show(); Log.d(TAG, "Error on keywordChanged.", t); } }); } RxTextView.textChanges(R.id.keyword) .map(CharSequence::toString) .map(String::trim) .filter(t -> !"".equals(t)) .flatMap(text -> service.listSuggestions(text)) .flatMapIterable(texts -> texts) .subscribe(adapter::add, e -> { SnackBar.make(view, "Something wrong!", LENGTH_LONG).show(); Log.d(TAG, "Error on keywordChanged.", e); }, () -> progressBar.setVisibility(GONE), __ -> { adapter.clear(); progressBar.setVisibility(VISIBLE); });
  • 43. RxJava로 짠 코드 테스트 할 수 있나요? (yn) yes, but think of the thread
  • 44. Congratulations! Level 2 • Hot/Cold Observable • more APIs of RxJava • Test for each onNext Next Quests http://wowguidessource.com/5-wow-leveling-tips-to-acquire-world-of-warcraft-level-85-fast.php • Future<T>, Single<T>
  • 45. Reference • ReactiveX 공식 사이트 http://reactivex.io/ • GDG 2014 - RxJava를 활용한 Functional Reactive Programming https://www.slideshare.net/waynejo/gdg-41029986 • 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기 https:// www.slideshare.net/jeokrang/rx-70197043 • 동기와 비동기, 블로킹과 논블로킹 http://nsinc.tistory.com/108 • http://nsinc.tistory.com/108