프로그래밍/Angular

[Angular] 옵저버블(Observable) 패턴을 이용한 날씨데이터 가져오기

Jay Tech 2017. 12. 29. 04:10
반응형

옵저버블 (Observable)


옵저버블 (Observable) 이란 데이터 스트림을 생성하는 객체를 말한다.


옵저버(Observer)는 데이터 스트림을 구독하여 사용하는 객체를 를 말한다.


일반적인 비동기 처리에 있어서 사용하는 callback함수나 Promise의 문제점


1) 한번에 하나의 데이터를 처리한다.


2) 서버로 보낸 요청을 취소할 수 없다.


Angular에서 날씨데이터를 가져오는 http 요청에 있어서 옵저버블을 구현해 보자.


출처 : Angular Development with TypeScript - 한장현


이 책에서 좋은 예제들을 제공한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { NgModule, Component } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { HttpModule, Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
 
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
 
@Component({
    selector : 'app',
    template : `
        <h2>Observable weather</h2>
        <input type="text" placeholder="Enter city" [formControl]="searchInput">
        <h3>{{ temperature }}</h3>
    `
})
export class AppComponent {
    private baseWeatherURL : string = 'http://api.openweathermap.org/data/2.5/weather?q=';
    private urlSuffix : string = '&units=metric&appid=[YOUR KEY]';
 
    searchInput : FormControl = new FormControl();
    temperature : string;
 
    constructor (private http : Http) {
        this.searchInput.valueChanges
            .debounceTime(200)
            .switchMap(city => this.getWeather(city))
            .subscribe(
                res => {
                    this.temperature =
                        `Current temperature is  ${res['main'].temp}℃, ` +
                        `humidity: ${res['main'].humidity}%`;
                },
                err => console.log("Can't get weather. Error code: %s, URL: %s", err.message, err.url),
                () => console.log("Weather is retrieved")
            );
    }
 
    getWeather (city : string) : Observable<Array<string>> {
        return this.http.get(this.baseWeatherURL + city + this.urlSuffix)
            .map(res => {
                console.log(res.json());
                return res.json();
            })
            .catch(err => {
                if (err.status === 404) {
                    console.log(`City ${city} not found`);
                    return Observable.of();
                } // empty observable
            });
    }
}
 
@NgModule({
    imports : [BrowserModule, ReactiveFormsModule,
        HttpModule],
    declarations : [AppComponent],
    bootstrap : [AppComponent]
})
class AppModule {}
 
platformBrowserDynamic().bootstrapModule(AppModule);
cs



line 18 : searchInput 이라는 컴포넌트 프로퍼티로 바인딩 된다.


line 31 ~ :  


함수들을 공식 RxJS 문서에서 발췌했다.


DebounceTime


debounceTime delays emitted by the source Observable, but drops previous delayed emissions if a new value arrives on the source Observable.

새로운 옵저버블이 들어오면 이전에 지연된 것들을 드랍한다고 한다.


" It's like delay, but passes only the most recent value from each burst of emissions. "


이 함수를 사용하지 않는다면 입력할 때 마다 이벤트가 발생할 것이다. 그래서 적당한 지연시간을 주는 것이다.


swithMap

Map to observable, complete previous inner observable, emit values

쓰는 이유는 효과를 취소하는데에 있다고 한다. 


On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.


옵저버블을 받아서 새로운 옵저버블을 반환한다.

subscribe

subscribe operator is the glue that connects an observer to an Observable.
옵저버와 옵저버블을 연결해주는 역할을 한다.

전형적으로 3가지의 함수들을 구현하게 된다. 
onNext, onError, onCompleted

getWeather 함수에서 결과값을 반환하기 전에 입력이 들어오게 되면 switchMap은 동작하고 있던 getWeather함수를 종료시켜 버린다. 즉 http요청도 종료되는 것이다.


Chrome 개발자 도구에서 인터넷 속도를 늦춰서 확인해 본다.








속도가 한참 느려졌다. 보면 404 error를 뿜는데 이것은 도중에 계속 계속 http요청이 가는 것을 종료시켜버린 결과이다. 


즉 옵저버블을 사용하면 아주 간단하게 불필요한 서버 요청을 취소하고 결과를 확인할 수 있다.

반응형