민자의 지식창고

Angular의 Observable 본문

개발노트/Angular

Angular의 Observable

전지적민자시점 2020. 8. 26. 09:08

Angular의 이벤트 사용과 HTTP에서 Observalble을 많이 사용합니다.

 

Observables의 의미는 다음과 같습니다.

여러 가지 값을 가질 수 있는 지연 컬렉션

 

Observables의 특징은 다음과 같습니다.

1.Observables는 lazy 하다. 각 구독자(subscriber)마다 새로운 뉴스 레터가 만들어집니다.

변하는 값에 대해 구독자(subscribe)들에게만 보냅니다.

 

2.Observables는 시간이 지남에 따라 여러 값을 가질 수 있습니다.

Promise와 차이점이 있다면, prosmise는 오직 하나의 값만을 반환합니다.

또 하나는 Observarbles의 구독을 취소 할 수 있다는 점입니다. Promise는 구독을 취소가 불가 하며, 결과가 반환되어 then()메서드를 통하게 됩니다. Promise의 resolve가 진행되고 있는 상태에서는 일반적으로 resolve가 실행되는 것을 막을 수 있는 방안은 없습니다.

 

 push vs pull

observables은 Push 시나리오를 따릅니다.

데이터의 생성자가 데이터 소비자와 커뮤니케이션 하는 방식은 2가지입니다

 

  • PUSH
    • pushing일 때, 데이터 생성자는 소비자가 데이터를 가져오는 시점을 결정합니다. 가장 일반적인 push 방법이 Promise입니다. Promise 전달자는 등록된 콜백(소비자)에게 reslove 된 값을 전달 하며, Promise는 메서드와 달리 callback에 그값이 push 되는 시기를 정확하게 결정합니다. 
  • PULL
    • pulling일 때, 소비자는 데이터 생성자로부터 데이터를 가져오는 시점을 결정합니다.  생산자는 언제 소비자에게 데이터를 전달했는지 모릅니다. 모든 Javascript 함수는 pull 시나리오를 사용합니다. 

 Angular의 Observables 

 Angular에서 두가지 방식으로 구현이 가능합니다.

 

1.비동기 파이프를 사용한 Templeate의 Observable 구독하는 방법

component의 Lifecycle 동안 구독을 처리합니다. Angular가 자동으로 구독하고 취소합니다. 

$ 기호 사용에 유의 하도록 합니다. 옵저버블 변수 이름에는 $기호를 사용하여, Observable로 간주합니다.

 

//typescript 소스
import { Component } from "@angular/core"
import { Observable } from "rxjs/Rx"

// client
import { HttpClient } from "../services/client"

// interface
import { IUser } from "../services/interfaces"

@Component({
    selector: "user-list",
    templateUrl:  "./template.html",
})
export class UserList {

    public users$: Observable<IUser[]>

    constructor(
        public client: HttpClient,
    ) {}

    // do a call to fetch the users on init of component
    // the fetchUsers method returns an observable
    // which we assign to the users$ property of our class
    public ngOnInit() {
        this.users$ = this.client.fetchUsers()
    }
}

// html 소스
<!-- We use the async pipe to automatically subscribe/unsubscribe to our observable -->
<ul class="user__list" *ngIf="(users$ | async).length">
    <li class="user" *ngFor="let user of users$ | async">
        {{ user.name }} - {{ user.birth_date }}
    </li>
</ul>

2. subscribe() 메소드를 사용하여 옵저버블을 구독합니다. 단점은 구독을 직접 관리해야 합니다.

//typescript 소스
import { Component } from "@angular/core"

// client
import { HttpClient } from "../services/client"

// interface
import { IUser } from "../services/interfaces"

@Component({
    selector: "user-list",
    templateUrl:  "./template.html",
})
export class UserList {

    public users: IUser[]

    constructor(
        public client: HttpClient,
    ) {}

    // do a call to fetch the users on init of component
    // we manually subscribe to this method and take the users
    // in our callback
    public ngOnInit() {
        this.client.fetchUsers().subscribe((users: IUser[]) => {

            // do stuff with our data here.
            // ....
            // asign data to our class property in the end
            // so it will be available to our template
            this.users = users
        })
    }
}

//html 소스
<ul class="user__list" *ngIf="users.length">
    <li class="user" *ngFor="let user of users">
        {{ user.name }} - {{ user.birth_date }}
    </li>
</ul>

 

 Creating and observable yourself

Angular가 제공한 옵저버블을 다루는 방법을 알았으므로,  간단하게 생성 하는 방법을 알아봅니다.

import { Observable } from "rxjs/Observable"

// create observable
const simpleObservable = new Observable((observer) => {
    
    // observable execution
    observer.next("bla bla bla")
    observer.complete()
})

// subscribe to the observable
simpleObservable.subscribe()

// dispose the observable
simpleObservable.unsubscribe()

 새로운 Observable()을 호출하고, 옵저버를 나타내는 하나의 인수를 전달 하면 됩니다. 이것을 Observer

 

Observable 구독하기 : 구독하지 않으면, 아무일도 일어나지 않습니다. 옵저버를 구독 할 때 subscribe()를 호출 할때마다 옵저버블에서 독립적으로 실행하게 됩니다. 동일한 Observable에 대해 구독 요청은 구독자간의 공유는 되지 않습니다.

 

옵저버블 실행하기

Observable 안의 코드는 observable의 실행을 나타냅니다. 

  • next : number나 Array 객체등의 값을 subscribe에게 보냅니다
  • error : 예외값을 보냅니다
  • complete : 값 x

실행을 취소하면 unsubscrib()를 호출하여, 구독을 취소 합니다.

728x90

'개발노트 > Angular' 카테고리의 다른 글

FormGroup안에서 Input 필드 disabled 동적 활성화  (0) 2020.10.19
Angular Unit test  (0) 2020.09.11
Angular Coding style Guide  (0) 2020.08.25
Element  (0) 2020.08.25
Angular Flex-Layout  (0) 2020.07.30