RxJava에서는 언제 맵과 플랫맵을 사용합니까?
언제 사용하십니까?map
대flatMap
RxJava에서요?
예를 들어, JSON을 포함하는 파일을 JSON을 포함하는 문자열에 매핑하려고 합니다.
사용.map
에 대응해야 합니다.Exception
어떻게든.하지만 어떻게?
Observable.from(jsonFile).map(new Func1<File, String>() {
@Override public String call(File file) {
try {
return new Gson().toJson(new FileReader(file), Object.class);
} catch (FileNotFoundException e) {
// So Exception. What to do ?
}
return null; // Not good :(
}
});
사용.flatMap
, 그것은 훨씬 더 장황하지만, 우리는 그 문제를 다음 순서로 전달할 수 있습니다.Observables
다른 곳을 선택하고 다시 시도해도 오류를 처리할 수 있습니다.
Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
@Override public Observable<String> call(final File file) {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override public void call(Subscriber<? super String> subscriber) {
try {
String json = new Gson().toJson(new FileReader(file), Object.class);
subscriber.onNext(json);
subscriber.onCompleted();
} catch (FileNotFoundException e) {
subscriber.onError(e);
}
}
});
}
});
심플한 것이 마음에 듭니다.map
단, 에러 처리flatmap
(장황함이 아니라)나는 이것에 대한 어떤 모범 사례도 본 적이 없는데, 나는 이것이 어떻게 실제로 사용되고 있는지 궁금하다.
map
이벤트를 다른 이벤트로 변환합니다. flatMap
하나의 이벤트를 0 이상의 이벤트로 변환합니다.(IntroToRx에서 인용)
json을 객체로 변환하고 싶기 때문에 map을 사용하면 충분합니다.
FileNotFoundException을 처리하는 것도 문제입니다(맵이나 플랫맵을 사용해도 이 문제는 해결되지 않습니다).
예외 문제를 해결하려면 Non checked 예외로 설정합니다.RX가 onError 핸들러를 호출합니다.
Observable.from(jsonFile).map(new Func1<File, String>() {
@Override public String call(File file) {
try {
return new Gson().toJson(new FileReader(file), Object.class);
} catch (FileNotFoundException e) {
// this exception is a part of rx-java
throw OnErrorThrowable.addValueAsLastCause(e, file);
}
}
});
platmap과 동일한 버전입니다.
Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
@Override public Observable<String> call(File file) {
try {
return Observable.just(new Gson().toJson(new FileReader(file), Object.class));
} catch (FileNotFoundException e) {
// this static method is a part of rx-java. It will return an exception which is associated to the value.
throw OnErrorThrowable.addValueAsLastCause(e, file);
// alternatively, you can return Obersable.empty(); instead of throwing exception
}
}
});
또한 platMap 버전에서는 오류에 불과한 새로운 Observatable을 반환할 수도 있습니다.
Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
@Override public Observable<String> call(File file) {
try {
return Observable.just(new Gson().toJson(new FileReader(file), Object.class));
} catch (FileNotFoundException e) {
return Observable.error(OnErrorThrowable.addValueAsLastCause(e, file));
}
}
});
FlatMap은 맵과 매우 비슷하게 동작합니다.다만, 적용하는 함수가 관찰 가능한 것을 반환하기 때문에, 비동기 연산에 매핑 하는 데 매우 적합합니다.
실제적인 의미에서 Map 적용 함수는 연결된 응답(관측 가능 반환 없음)에 대해 변환을 수행하지만 FlatMap 적용 함수는 다음을 반환합니다.Observable<T>
그렇기 때문에 메서드 내에서 비동기 콜을 발신할 예정이라면 FlatMap을 권장합니다.
요약:.
- 맵이 T형 개체를 반환합니다.
- FlatMap은 관찰 가능을 반환합니다.
명확한 예는 http://blog.couchbase.com/why-couchbase-chose-rxjava-new-java-sdk 에서 확인할 수 있습니다.
Couchbase Java 2.X Client는 Rx를 사용하여 비동기 콜을 편리한 방법으로 제공합니다.Rx 를 사용하고 있기 때문에 메서드 맵과 플랫 맵을 사용하고 있기 때문에 일반적인 개념을 이해하는데 도움이 될 수 있습니다.
오류를 처리하려면 susbcriber에서 onError를 덮어씁니다.
Subscriber<String> mySubscriber = new Subscriber<String>() {
@Override
public void onNext(String s) { System.out.println(s); }
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
};
다음 문서를 보시면 도움이 될 수 있습니다.http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
RX 에러를 관리하는 방법에 관한 적절한 소스는, https://gist.github.com/daschl/db9fcc9d2b932115b679 를 참조해 주세요.
당신의 경우 입력과 출력은 각각1개뿐이기 때문에 지도가 필요합니다.
맵 제공 함수는 단순히 아이템을 수신하고 더 멀리(한 번만) 방출되는 아이템을 반환합니다.
platMap - 제공 함수는 항목을 받아들인 후 "Observatable"을 반환합니다. 즉, 새 "Observatable"의 각 항목이 더 아래로 별도로 방출됩니다.
코드일 수도 있습니다.
Observable.just("item1").map( str -> {
System.out.println("inside the map " + str);
return str;
}).subscribe(System.out::println);
Observable.just("item2").flatMap( str -> {
System.out.println("inside the flatMap " + str);
return Observable.just(str + "+", str + "++" , str + "+++");
}).subscribe(System.out::println);
출력:
inside the map item1
item1
inside the flatMap item2
item2+
item2++
item2+++
문제는 RxJava에서 언제 map vs platMap을 사용합니까?간단한 데모가 더 구체적이라고 생각합니다.
출력된 항목을 다른 유형으로 변환하는 경우 파일을 String으로 변환하면 맵과 플랫맵이 모두 작동합니다.하지만 나는 지도 운영자가 더 명확하기 때문에 선호한다.
하지만 어떤 곳에서는flatMap
마술은 할 수 있지만map
할 수 없어요. 예를 들어, 사용자 정보를 얻고 싶은데 로그인 할 때 먼저 아이디를 받아야 해요.분명히 나는 두 가지 요청이 필요하고 그것들은 순서대로 되어 있다.
시작합시다.
Observable<LoginResponse> login(String email, String password);
Observable<UserInfo> fetchUserInfo(String userId);
다음 두 가지 방법이 있습니다. 하나는 로그인을 위해 반환됩니다.Response
및 사용자 정보를 가져오기 위한 다른 명령어입니다.
login(email, password)
.flatMap(response ->
fetchUserInfo(response.id))
.subscribe(userInfo -> {
// get user info and you update ui now
});
보시다시피 function platMap applicate에서는 처음에 사용자 ID를 취득합니다.Response
사용자 정보를 가져옵니다.두 가지 요청이 완료되면 UI 업데이트나 데이터 저장 등의 작업을 수행할 수 있습니다.
단,map
그렇게 좋은 코드를 쓰면 안 돼한마디로 말해서flatMap
를 사용하면 요청을 시리얼화할 수 있습니다.
내가 생각하기로는 넌 이 모든 걸flatMap
그 안에 넣고 싶었던 기능이map()
반환하다Observable
이 경우에도, 이 기능을 사용해 주세요.map()
현실적이진 않을 겁니다왜 그런지 설명해 드릴게요.
만약 그런 경우엔, 당신이 계속 이 일을 하기로 결정했다면map
, 를 얻을 수 있습니다.Observable<Observable<Something>>
예를 들어, 가상 RxGson 라이브러리를 사용했을 경우, 이 라이브러리는Observable<String>
그것부터toJson()
방법(단순히 반환하는 방법)String
)는 다음과 같습니다.
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}); // you get Observable<Observable<String>> here
현시점에서는 꽤 까다로울 것이다subscribe()
그렇게 관찰할 수 있는 사람까지요그 안에서 당신은 그것을 얻을 것이다.Observable<String>
다시 한 번 이 부분에 대해서subscribe()
가치를 얻기 위해서요.실용적이지도 않고 보기에도 좋지 않죠
따라서 이 방법을 유용하게 사용하기 위해 관측 가능한 관측 가능 데이터를 "평탄화"하는 것이 한 가지 방법입니다(_flat_Map이라는 이름이 어디에서 유래했는지 알 수 있습니다).RxJava는 관측 가능한 것을 평평하게 하기 위한 몇 가지 방법을 제공하며 단순성을 위해 우리가 원하는 것이 병합이라고 가정합니다.Merge는 기본적으로 관측 가능한 것들을 많이 가져다가 어느 것이든 방출될 때마다 말이죠.(많은 사람들은 스위치가 더 나은 디폴트라고 주장할 것이다.단, 1개의 값만 방출하고 있다면 상관없습니다.)
따라서 이전 스니펫을 수정하면 다음과 같이 됩니다.
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}).merge(); // you get Observable<String> here
이것은 훨씬 더 편리합니다.그것(또는 매핑, 필터링 등)에 가입하면String
가치. (또한 명심해, 그런 변종인merge()
RxJava에는 없습니다만, Marge의 개념을 이해하셨다면, 어떻게 동작하는지도 이해해 주셨으면 합니다.)
그러니까 기본적으로는merge()
아마도 그것이 성공했을 때에만 도움이 될 것이다.map()
관찰 가능한 것을 반환하기 때문에 반복해서 입력할 필요가 없습니다.flatMap()
줄여서 만든 거예요.매핑 기능을 일반과 동일하게 적용합니다.map()
하지만 나중에 반환된 값을 내보내는 대신 "평탄화"(또는 병합)하기도 합니다.
이것이 일반적인 사용 사례입니다.모든 곳에서 Rx를 사용하는 코드베이스에서 가장 유용하며 관측 가능을 반환하는 여러 가지 메서드를 사용할 수 있습니다. 이러한 메서드는 관측 가능을 반환하는 다른 메서드와 연결하려고 합니다.
사용 사례에서도 유용합니다.map()
에서 방출되는 값은 1개만 변환할 수 있습니다.onNext()
에서 방출되는 다른 가치로onNext()
그러나 값을 여러 개로 변환하거나 값을 전혀 입력하지 않거나 오류를 발생시킬 수 없습니다.그리고 akarnokd가 그의 답변에서 썼듯이(그리고 그는 아마도 일반적으로 나보다 훨씬 더 똑똑하지만 적어도 RxJava에 관해서는) 당신은 당신의 답변에서 예외를 던져서는 안 됩니다.map()
그 대신,flatMap()
그리고.
return Observable.just(value);
만사가 잘 되면
return Observable.error(exception);
실패했을 때.
자세한 내용은http://https://stackoverflow.com/a/30330772/1402641 를 참조해 주세요.
여기 간단한 썸룰을 사용하면 언제 사용할지 결정할 수 있습니다.flatMap()
에 걸쳐서map()
Rx의Observable
.
당신이 고용하기로 결정되면map
변환 코드를 작성하여 오브젝트를 반환할 수 있습니다.
변혁의 최종 결과로 반환되는 것은 다음과 같습니다.
관찰할 수 없는 오브젝트를 사용하면 됩니다.그리고
map()
이 물체를 관찰 가능한 물질로 감싸서 방출합니다.오브젝트를 사용하면 됩니다.그리고.
flatMap()
Observatable을 개봉하고 반환된 객체를 선택한 후 자체 Observatable로 감싼 후 내보냅니다.
예를 들어 입력 파라미터의 Title Case(String input Param) 오브젝트를 반환하는 메서드 title Case(String input Param)가 있다고 합시다.이 메서드의 반환 유형은 다음과 같습니다.String
또는Observable<String>
.
반환 타입이
titleCase(..)
단순한 것으로 되어 있었다String
를 사용하여map(s -> titleCase(s))
반환 타입이
titleCase(..)
될 예정이었다Observable<String>
를 사용하여flatMap(s -> titleCase(s))
그게 밝혀졌으면 좋겠어요.
난 그냥 그걸 더하고 싶었어flatMap
함수 내에서 사용자 정의 Observable을 사용할 필요가 없으며 표준 공장 방법/운영자에 의존할 수 있습니다.
Observable.from(jsonFile).flatMap(new Func1<File, Observable<String>>() {
@Override public Observable<String> call(final File file) {
try {
String json = new Gson().toJson(new FileReader(file), Object.class);
return Observable.just(json);
} catch (FileNotFoundException ex) {
return Observable.<String>error(ex);
}
}
});
일반적으로 RxJava에 가능한 한 많은 세이프가드를 배치했지만 가능하면 onXX 메서드와 콜백에서 (Runtime-) 예외를 발생시키지 않도록 해야 합니다.
이 시나리오에서는 맵을 사용하기 위해 새로운 관찰 가능이 필요하지 않습니다.
Exceptions.propagate를 사용해야 합니다.Exceptions.propagate는 선택한 예외를 rx 메커니즘으로 전송할 수 있도록 래퍼입니다.
Observable<String> obs = Observable.from(jsonFile).map(new Func1<File, String>() {
@Override public String call(File file) {
try {
return new Gson().toJson(new FileReader(file), Object.class);
} catch (FileNotFoundException e) {
throw Exceptions.propagate(t); /will propagate it as error
}
}
});
다음으로 서브스크라이버에서 이 에러를 처리할 필요가 있습니다.
obs.subscribe(new Subscriber<String>() {
@Override
public void onNext(String s) { //valid result }
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { //e might be the FileNotFoundException you got }
};);
훌륭한 투고가 있습니다.http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/
RxJava 맵과 플랫 맵
둘 다 변환 연산자이지만map
1 대 1의 관계와flatMap
는 1-0 이상의 관계가 있습니다.
map
그리고.flatmap
로 스트림을 내뿜다.map
(1개의 요소만).flatmap
- 0/many 요소
map
단일 요소를 방출하고flatmap
원소의 흐름을 방출하다
지도 연산자
map(new Function<A, B>() {
@Override
public B apply(A a) throws Exception {
B b = new B(a);
return b;
}
})
플랫맵 연산자
flatMap(new Function<A, ObservableSource<B>>() {
@Override
public ObservableSource<B> apply(A a) throws Exception {
return foo(a);
}
})
경우에 따라 관측 가능한 다른 관측 가능한 체인이 반환될 수 있습니다.'플랫맵'은 첫 번째 관측치에 묻혀 있는 두 번째 관측치의 압축을 풀고 두 번째 관측 가능한 데이터에 직접 액세스할 수 있도록 하는 것입니다.
플랫맵은 관측 가능한 것을 관측 가능한 것에 매핑합니다.항목을 항목에 매핑합니다.
플랫맵은 더 유연하지만 맵은 더 가볍고 직접적이기 때문에 사용 사례에 따라 달라집니다.
비동기(스위칭스레드 포함)를 실행하고 있는 경우 플랫맵을 사용해야 합니다.이는 Map이 컨슈머가 폐기되었는지(Lightweight-ness의 일부) 확인하지 않기 때문입니다.
언급URL : https://stackoverflow.com/questions/22847105/when-do-you-use-map-vs-flatmap-in-rxjava
'IT이야기' 카테고리의 다른 글
Vue/Vuex 알 수 없는 작업 유형 (0) | 2022.07.05 |
---|---|
매크로에서 의미 없는 do-while 및 if-else 문을 사용하는 이유는 무엇입니까? (0) | 2022.07.05 |
어레이[idx+]+="a"가 Java 8에서 한 번 idx가 증가하지만 Java 9와 10에서는 두 번 증가하는 이유는 무엇입니까? (0) | 2022.07.05 |
옵션에서의 사용 (0) | 2022.07.05 |
Java: 열거에 지정된 문자열이 포함되어 있는지 확인하시겠습니까? (0) | 2022.07.04 |