sync, async
Rx에서 가장 중요한 개념인 Observable에 대해 이야기하기전에 우선 동기(sync)와 비동기(async) 프로그래밍에 대해 간단하게 설명하고자 한다.
private func loadImage(from imageUrl: String) -> UIImage? {
guard let url = URL(string: imageUrl) else { return nil }
guard let data = try? Data(contentsOf: url) else { return nil }
let image = UIImage(data: data)
return image
}
여기 URL요청을 통해 이미지를 불러와 UIImage 형태로 리턴해주는 함수가 있다. 동기방식으로 처리할경우 이미지를 요청하고 요청에 대한 응답을 받아야만 다음처리가 가능해진다. 이에 반해 비동기방식은 요청을 하고난 후 응답을 받기 전에 다음 작업들을 이어서 처리하다가 요청에 대한 응답이 수신되면 응답에 대한 처리를 마저 하게되는 방식이다. 즉 동기방식은 요청에 대한 응답이 올때 까지 대기. 비동기방식은 요청에 대한 응답을 대기하지 않고 다음작업들을 처리. 차이라고 보면 된다. 아래의 코드를 통해 두 방법의 차이를 확인해보자.
//동기방식
@IBAction func onLoadSync(_ sender: Any) {
let image = loadImage(from: IMAGE_URL)
imageView.image = image
}
//비동기방식
@IBAction func onLoadAsync(_ sender: Any) {
DispatchQueue.global().async {
let image = self.loadImage(from: self.IMAGE_URL)
DispatchQueue.main.async {
self.imageView.image = image
}
}
}
우측의 시간카운터를 보면 동기방식과 비동기방식의 차이를 확인할 수 있다.
동기방식으로 요청을 처리할경우, 응답을 받을 때까지 아무런 작업을 할 수 없게된다. 이렇게 동기방식으로 작성된 앱은 사용자에게 큰 불편을 유발하게 된다. 하지만 위의 예시처럼 비동기 방식으로 작성하게되면 코드의 가독성이 떨어진다.
Observable stream
다음은 RxSwift로 작성된 비동기 코드를 보자.
var disposebag = DisposeBag()
@IBAction func onLoadRxAsync(_ sender: Any) {
Observable.just(self.IMAGE_URL)
.subscribe(on: ConcurrentDispatchQueueScheduler(qos: .default))
.map{self.loadImage(from: $0)}
.observe(on: MainScheduler.instance)
.subscribe(onNext: { image in
self.imageView.image = image
})
.disposed(by: disposebag)
}
처음 Rx코드를 보았을때 오히려 코드라인이 늘어나서 당황했다. 하지만 코드의 흐름을 보면 들여쓰기와 중괄호가 아닌 Observable에서 시작되는 메소드들로 흘러가는 모양을 볼 수 있고, 마지막 subscribe부분에서 UI처리를 하는 모습을 볼 수 있다. 이러한 형태가 바로 이전글에 Rx의 정의를 이해할 수 있는 좋은 예시이다.
An API for asynchronous programming
with "observable streams"
Observable에서 파생되는 stream(흐름)을 통한 비동기 프로그래밍 API. 즉 Observable에서 시작되는 반환값이 여러가지 Operator, Subject, Scheduler들로 이루어진 흐름을 통해 비동기 프로그래밍을 할 수 있는 API라고 할 수 있다. 이것이 Rx의 정의이다.
참고영상
'iOS > RxSwift' 카테고리의 다른 글
scheduler (0) | 2022.08.31 |
---|---|
next, error, complete (0) | 2022.08.19 |
operator (0) | 2022.07.21 |
subscribe, dispose (0) | 2022.06.15 |
ReactiveX (0) | 2022.05.30 |