연산자는 관찰 가능한 물체를 변환하는 문제를 해결하는 데 사용됩니다. 연산자는 관찰 가능성과 최종 가입자 사이에 관찰 가능한 이벤트를 수정하는 데 사용됩니다. Rxjava는 많은 유용한 연산자를 제공합니다.
예를 들어, 맵 연산자는 한 이벤트를 다른 이벤트로 변환하는 데 사용됩니다.
Observable.just ( "Hello, World!") .map (new func1 <String, String> () {@override public String (string s) {return s + "-dan";}}) .subscribe (s-> system.out.println (s)); Lambda를 사용하면 단순화 할 수 있습니다
Observable.just ( "Hello, World!") .map (s-> s + "-dan") .subscribe (s-> system.out.println (s));
시원하지 않습니까? Map () 연산자는 관찰 가능한 물체를 변환하는 데 사용됩니다. MAP 연산자는 관찰 가능한 객체를 반환하여 체인 호출을 구현할 수 있고 MAP 연산자는 관찰 가능한 객체에서 여러 번 사용되며 가장 간단한 데이터는 가입자 객체로 전달됩니다.
MAP 운영자 고급
MAP 연산자의 더 흥미로운 점은 관찰 가능한 객체에 의해 반환 된 유형을 반환 할 필요가 없다는 것입니다. 맵 연산자를 사용하여 새 데이터 유형을 방출하는 관찰 가능한 객체를 반환 할 수 있습니다.
예를 들어, 위의 예에서 가입자는 반환 된 문자열에 신경 쓰지 않지만 문자열의 해시 값을 원합니다.
Observable.Just ( "Hello, World!") .map (new func1 <String, integer> () {@override public integer call (string s) {return s.hashcode ();}}) .subscribe (i-> system.out.println (integer.tostring (i)); 매우 흥미 롭습니까? 최초의 관찰 가능한 것은 문자열을 반환하고 최종 가입자는 정수를받습니다. 물론 Lambda를 사용하면 코드를 더욱 단순화 할 수 있습니다.
Observable.just ( "Hello, World!") .map (s-> s.hashcode ()) .subscribe (i-> system.out.println (integer.tostring (i)));
앞에서 언급했듯이 구독이 적을수록 더 좋습니다. 다른 맵 연산자를 추가합시다.
Observable.just ( "Hello, World!") .map (s-> s.hashcode ()) .map (i-> integer.tostring (i)) .subscribe (s-> system.out.println (s));
확신하지 않습니까?
우리의 예가 당신을 설득하기에는 너무 간단하다고 생각하십니까? 다음 두 가지 점을 이해해야합니다.
1. 관찰 가능하고 가입자는 무엇이든 할 수 있습니다
관찰 가능한 것은 데이터베이스 쿼리 일 수 있으며 가입자는 쿼리 결과를 표시하는 데 사용됩니다. 관찰 가능한 것은 화면의 클릭 이벤트 일 수 있으며 가입자는 클릭 이벤트에 응답하는 데 사용됩니다. 관찰 가능한 것은 네트워크 요청 일 수 있으며 가입자는 요청 결과를 표시하는 데 사용됩니다.
2. 관찰 가능 및 가입자는 중간 변환 과정과 무관합니다.
관찰 가능성과 가입자 사이에 여러 맵을 추가하거나 감소시킬 수 있습니다. 전체 시스템은 조합 가능하며 운영 데이터는 매우 간단한 프로세스입니다.
예
1. 준비
다음과 같은 방법이 있다고 가정합니다.
이 메소드는 입력 문자열 (AHHA, 검색 엔진)에 따라 웹 사이트의 URL 목록을 반환합니다.
Observable <list <string >> 쿼리 (문자열 텍스트);
이제 문자열을 쿼리하고 결과를 표시 할 수있는 강력한 시스템을 구축하고 싶습니다. 이전 블로그의 내용을 기반으로 다음 코드를 작성할 수 있습니다.
Query ( "Hello, World!") .SubScribe (urls-> {for (String URL : urls) {System.out.println (url);}});물론 위의 코드로 인해 데이터 흐름을 변경하는 기능을 잃게 되었기 때문에 이러한 종류의 코드는 용납 할 수 없습니다. 각 URL을 변경하려면 가입자에서만 수행 할 수 있습니다. 우리는 그런 멋진 map () 연산자를 사용하지 않았습니다! ! !
물론지도 연산자를 사용할 수 있습니다. 맵의 입력은 URL 목록입니다. 처리 할 때는 여전히 각각을 가로 질러야하며 이는 또한 매우 고통 스럽습니다.
다행스럽게도 Observable.From () 메소드도 있습니다.이 메소드는 입력으로 수집을 수신 한 다음 한 번에 가입자에게 요소를 출력합니다.
Observable.from ( "url1", "url2", "url3") .SubScribe (url-> system.out.println (url));
이 방법을 지금 당장 장면에 사용합시다.
Query ( "Hello, World!") .Subscribe (urls-> {Observable.from (urls) .Subscribe (url-> system.out.println (url));});
각 루프마다 제거되지만 코드는 여전히 지저분 해 보입니다. 여러 중첩 구독은 추악하고 수정하기가 어려울뿐만 아니라 더 심각하게 보이지만, 우리가 아직 언급하지 않은 rxjava의 일부 기능을 파괴 할 것입니다.
2. 개선
구주가 여기 있습니다. 그는 flatmap ()입니다.
Observable.flatmap ()은 입력으로 관찰 가능한 결과의 출력을 수신하고 동시에 관찰 가능한 다른 출력을 입력합니다. 코드를 직접 봅니다.
query ( "Hello, World!") .flatmap (new func1 <list <string>, Observable <String >> () {@override public vercipable <string> call (list <string> urls) {return observable.from (urls);}}) .subscribe (url-> system.out.println (url)); 여기에 전체 기능 코드를 게시하여 무슨 일이 일어나고 있는지 이해할 수 있습니다. Lambda를 사용하면 코드 길이를 크게 단순화 할 수 있습니다.
query ( "Hello, World!") .flatmap (urls-> veriversabable.from (urls)) .subscribe (url-> system.out.println (url));
flatmap ()가 이상하게 보입니까? 왜 관찰 가능한 다른 반환입니까? FlatMap을 이해하는 데있어 핵심 요점은 FlatMap의 새로운 관찰 가능한 출력이 가입자에서 받고 싶은 것입니다. 이제 가입자는 더 이상 List <string>을받지 않고 Observable.from ()의 출력과 마찬가지로 일부 단일 문자열의 열을받습니다.
이 부분은 내가 Rxjava를 처음 배웠을 때 가장 어려운 부분입니다. 갑자기 그것을 깨달았을 때, rxjava의 많은 질문들이 해결되었습니다.
3. 더 나을 수 있습니다
flatmap ()은 실제로 더 나은 아이디어가 아니며 반환하려는 관찰 가능한 객체를 반환 할 수 있습니다.
예를 들어 다음 방법은 다음과 같습니다.
// 웹 사이트의 제목을 반환하고 404 인 경우 null Observable <string> getTitle (String URL)을 반환합니다.
이전 예제에 따라 이제 더 이상 URL을 인쇄하고 싶지 않고 대신받는 각 웹 사이트의 제목을 인쇄합니다. 문제는 내 메소드가 한 번에 하나의 URL에서만 전달 될 수 있고 리턴 값은 문자열이 아니라 문자열을 출력하는 관측형 객체라는 것입니다. flatMap ()을 사용하면이 문제를 해결할 수 있습니다.
query ( "hello, world!") .flatmap (urls-> personspable.from (urls)) .flatmap (new func1 <String, Observable <string >> () {@override public verible <string> call (string url) {return gettitle (url);}}). 4. Lambda 사용 :
query ( "Hello, World!") .flatmap (urls-> veriverse.from (urls)) .flatmap (url-> gettitle (url)) .subscribe (title-> system.out.println (title));
믿어지지 않습니까? 실제로 여러 독립적 인 방법을 결합하여 관찰 가능한 객체를 함께 반환 할 수 있습니다! 아주 잘 생겼어!
그 이상으로, 나는 또한 두 개의 API의 호출을 사슬로 결합했습니다. 우리는 가능한 많은 API 호출을 가능한 한 많이 연결할 수 있습니다. 모든 API 호출을 동기화 한 다음 모든 API 호출의 콜백 결과를 표시 할 데이터에 결합하는 것이 얼마나 고통 스러운지 알아야합니다. 여기서 우리는 콜백 지옥 (다층 중첩 된 콜백을 피하고 코드를 읽고 유지하기가 어렵음)을 성공적으로 피했습니다. 이제 모든 논리 가이 간단한 반응 형 호출로 싸여 있습니다.
5. Rich Operators <br /> 지금까지, 우리는 두 명의 운영자와 연락을 취했으며 Rxjava에는 더 많은 연산자가 있으므로 다른 운영자를 사용하여 코드를 개선합니까?
getTitle () URL이 존재하지 않으면 NULL을 반환합니다. 우리는 "null"을 출력하고 싶지 않으면 반환 된 제목 목록에서 NULL 값을 필터링 할 수 있습니다!
query ( "Hello, World!") .flatmap (urls-> verivable.from (urls)) .flatmap (url-> gettitle (url)) .filter (title -> title! = null) .subscribe (title-> system.out.println (title));
필터 ()는 입력과 동일한 요소를 출력하고 점검 기준을 충족하지 않는 요소를 필터링합니다.
최대 5 개의 결과 만 원한다면 :
query ( "Hello, World!") .flatmap (urls-> verivable.from (urls)) .flatmap (url-> gettitle (url)) .filter (title -> title! = null) .take (5) .subscribe
() 최대 결과 수를 출력합니다.
인쇄하기 전에 각 타이틀을 디스크에 저장하려면 :
query ( "Hello, World!") .flatmap (urls-> veriverse.from (urls)) .flatmap (url-> gettitle (url)) .filter (title -> title! = null) .take (5) .doonnext (title-> savetitle (title)).
doonnext ()를 사용하면 여기에 제목을 저장하는 것과 같이 한 번에 요소를 출력하기 전에 추가 작업을 수행 할 수 있습니다.
여기서 데이터 흐름을 작동하는 것이 얼마나 쉬운 지 쉽게 알 수 있습니까? 원하는만큼의 작업을 추가하고 코드를 망칠 수 있습니다.
Rxjava에는 많은 수의 연산자가 포함되어 있습니다. 운영자의 수는 약간 무섭지 만 어떤 연산자를 사용할 수 있는지 알 수 있도록 하나씩 확인하는 것이 좋습니다. 이러한 연산자를 이해하는 데 시간이 좀 걸릴 수 있지만 일단 이해하면 rxjava의 힘을 완전히 파악할 수 있습니다.
사용자 정의 연산자도 쓸 수도 있습니다! 이 블로그는 운영자를 사용자 정의 할 의도가 없습니다. 원한다면 직접 Google을 보내십시오.
기분이 어떻습니까?
글쎄, 당신은 회의론자이고 설득하기가 어렵습니다. 왜 이들 운영자에 관심이 있습니까?
운영자는 데이터 스트림에 무엇이든 할 수 있기 때문입니다.
일련의 연산자를 연결하면 복잡한 논리를 달성 할 수 있습니다. 코드는 결합 할 수있는 일련의 스 니펫으로 나뉩니다. 이것은 반응 기능 프로그래밍의 매력입니다. 더 많이 사용할수록 프로그래밍 사고를 더 많이 바꿀 것입니다.
또한 Rxjava를 사용하면 데이터를보다 쉽게 처리 할 수 있습니다. 마지막 예에서는 두 개의 API를 호출하고 API에서 반환 한 데이터를 처리하고 디스크에 저장합니다. 그러나 가입자는 이것을 알지 못하고 관찰 가능한 <string> 객체를 받고 있다고 생각합니다. 좋은 포장재도 코딩 편의를 제공합니다!
세 번째 부분에서는 오류 처리 및 동시성과 같은 rxjava의 다른 멋진 기능을 소개합니다. 이는 데이터를 처리하는 데 직접 사용되지 않습니다.