안녕하세요. 점냥입니다:)
이번 포스팅에서도 굉장히 오랜만에 인사드린 것에 대해서 죄송하다는 말씀 먼저 드려야 할 것 같습니다... ㅎ
변명을 하자면 취준, 동아리, 요즘 새벽 시간에 열심히 활동 중인 디스코드로 인해 블로그 활동이 소홀했습니다. 반성합니다 ㅠ
이번 포스팅에서는 현재 개발 중인 프로젝트에서 고민했던 주제인 Completable 결합하는 방법입니다.
이미지를 한 개 저장할 때
진행 중인 프로젝트에서는 Firebase Storage에 이미지를 저장하고 결과 값으로 Completable
스트림을 반환합니다.
ViewModel에서 코드는 다음과 같이 같습니다.
class MainViewModel(
private val imageService: ImageService
) : BaseViewModel() {
private val _isUploadSuccess = SingleLiveData<Unit>()
val _isUploadSuccess: SingleLiveData<Unit>() = _isUploadSuccess
fun uploadImage(imageUrl: String) {
imageService.saveImage(imageUrl)
.subsribeOn(..)
.observeOn(..)
.subscribe({
_isUploadSuccess.value = Unit
}, { exception ->
Log.e(..)
}).addToDisposable()
}
}
위 코드를 보면 이미지 URL을 매개변수로 받고 imageService 객체를 통해 서버에 이미지를 저장합니다.
그리고 스트림은 Completable이기 때문에 결과는 Complete or Error입니다. 즉 성공과 실패를 쉽게 판단할 수 있습니다.
이미지를 여러 개 저장할 때
예를 들어 이미지를 5개를 저장하려는 데 이 중 한 개라도 실패한다면 이미지 업로드에 실패한 것으로 판단하고 싶습니다. 이런 상황에서 위 코드 uploadImage
함수를 그대로 사용할 수 있을 까요? 이미지 저장은 비동기인 것을 주의해야 합니다. 언제 5개 이미지가 저장이 성공했다는 것을 판단할 수 있을 까요?
답은 andThen
함수를 사용하면 됩니다.
andThen 함수는 여러 개의 스트림을 연결하여 하나의 결과를 반환하는 함수입니다.
그림에서 알 수 있듯이 순차적으로 실행이 되며 앞선 결과에서 오류가 발생할 경우 바로 오류를 보고한 뒤 종료되게 됩니다.
예시 코드
class MainViewModel(
private val imageService: ImageService
) : BaseViewModel() {
private val _isUploadSuccess = SingleLiveData<Unit>()
val _isUploadSuccess: SingleLiveData<Unit>() = _isUploadSuccess
fun uploadImages(images: List<String>) {
var rootCompletable = Completable.fromSingle(Single.just(1))
images.forEach { imageUrl ->
rootCompletable = rootCompletable.andThen(
imageService.saveImage(imageUrl)
)
}
rootCompletable
.subsribeOn(..)
.observeOn(..)
.subscribe({
_isUploadSuccess.value = Unit
}, { exception ->
Log.e(..)
}).addToDisposable()
}
}
'Language > RxJava' 카테고리의 다른 글
[RxJava] Operators - 변환 (0) | 2021.01.24 |
---|---|
[RxJava] Operators - 생성 (0) | 2021.01.24 |
[RxJava] Hot Observable (0) | 2020.11.05 |
[RxJava] BaseClasses (0) | 2020.10.26 |
Hello RxJava, Rx는 왜 사용할까? (3) | 2020.10.17 |