[angular] Promise를 이용한 Service와 Compnent의 HTTP 데이터 처리
출저 및 참고 사이트 :
https://programmingsummaries.tistory.com/325
https://one-it.tistory.com/entry/Promise-%EC%A0%95%EB%A6%AC-asyncawait-%EC%82%AC%EC%9A%A9%EB%B2%95-then%EA%B3%BC%EC%9D%98-%EC%B0%A8%EC%9D%B4
Javascirpt Pormise
- Promise 패턴을 사용하면, 비동기적인 작업들을 순서대로, 순차대로 진행하거나, 병렬로 진행할수 있게된다.
- 현재 Promise 패턴은 ECMA Script 6 스펙에 정식으로 포함되었다.
Promise 기초 예제)
//Promise 선언
var _promise = function (param) {
return new Promise(function (resolve, reject) {
// 비동기를 표현하기 위해 setTimeout 함수를 사용
window.setTimeout(function () {
// 파라메터가 참이면,
if (param) {
// 해결됨
resolve("해결 완료");
}
// 파라메터가 거짓이면,
else {
// 실패
reject(Error("실패!!"));
}
}, 3000);
});
};
// new Promise로 Promise 가 생성되는 직후부터 resolve 나 reject가 호출 되기 전까지의 순간을 pending 상태라고 볼 수 있다.
// 이후 비동기 작업이 마친 뒤 결과물을 약속대로 잘 줄 수 있다면
// 첫번째 파라메터로 주입되는 resolve 함수를 호출하고, 실패했다면 두번째 파라메터로 주입되는 reject 함수를 호출한다.
//Promise 실행
// _promise() 를 호출하면 Promise 객체가 리턴된다.
_promise(true)
.then(function (text) {
// Promise 객체에는 정상적으로 비동기 작업이 완료되었을때 호출하는 then 이라는 API 가 존재한다.
// 성공시 호출할 함수
console.log(text);
}, function (error) {
// 실패시 호출할 함수
console.error(error);
});
var _promise = function (매개변수) {
return new Promise(function (resolve, reject)) {
비 동기적으로 동작하는 함수, 코드
}
}
_promise(매개변수).then( { 성공시 처리함수 구현}, {실패시 처리함수 구현 } )
Primise 선언부
- pending : 아직 약속을 수행 중인 상태(fullfilled 혹은 reject가 되기 전)
- fulfilled : 약속(promise)이 지켜진 상태
- rejected : 약속(promise)가 어떤 이유에서 못 지켜진 상태
- settled : 약속이 지켜졌든 안지켜졌든 일단 결론이 난 상태
체이닝형태로 연결된 상태에서 비동기 작업이 중간에 에러가나면 처리 Promise.catch API
여러 프로미스가 모두 완료될 때 실행 Promise.all API
프로미스의 async 와 await
- 비동기 처리르 없이 코드를 동작하면 undefined 가 출력되는 경우가 있다.
- Promise를 반환하는 함수 반환값을 사용하기 까지 코드를 지연시키기 위해 async, await 를 사용한다.
Async, await 활용 예제)
const sampleFunc = async () => {
const result = await asyncFunc() // asyncFunc 함수는 Promise 객체를 반환한다.
// asyncFunc() 함수의 실행결과가 반한되어 result에 할당되기 전까지, await 키워드가 console.log 함수의 실행을 지연시켜준다.
console.log(result)
// Proimise 객체를 반환하는 함수 asyncFunc앞에 await 를 붙이고, 이를 포함하는 함수 앞에 async를 붙여준다.
// await 키워드를 쓰려면 반드시 async 키워드로 선언된 함수 내부여야 한다.
}
then 과 async/await 의 차이
- then : { } 코드 블록 밖의 함수는 동기화 불가
- async / await : { } 코드 블록 밖의 함수도 동기화가 진행됨
- async/await 를 사용하면 promise.then().catch() 처럼 reject를 잡아낼 수 없기 때문에 try catch 문을 사용해야 한다.
출저 및 참고 사이트 :
Angular HttpClient 라이브러리를 이용한 Promise
기본적인 Http 요청 예제)
constructor(
private http: HttpClient
) {}
public getData(): void {
this.http.get('request url')
.subscribe((data: any): void => {
//do somthing with data
}, error => {
//handle error
});
}
- subscribe 메서드를 이용해 데이터를 받아 처리
- subscribe의 두 번째 인자는 에러를 처리하는 콜백 함수
- 단점 : 콤포넌트에서 직접 Http 통신을 하는 것보다 서비스로 따로 빼서 관리하는 것이 유지보수 측면에서 좋다. (MVVM 패턴)
서비스에서 HTTP 메소드 처리 후, Component 로 데이터 전달
- Component를 콜백호출로 데이터 처리를 하면, 코드가 길어지니 HTTP 통신 메소드를 Promise로 만들어서 Component 에게 데이터를 전달하는 방식으로 한다.
HttpClient 에서 제공하는 toPromise() 메서드 사용 예제)
Service.TS 파일
constructor(
private http: HttpClient
) {}
public async getData(): Promise<any> {
return await this.http.get('request url').toPromise();
//or return await this.http.get('request url').toPromise() as Data;
}
Component.TS 파일
any_service : Any_service;
this.any_service.getData().then(value => 전달받은 값 처리 구현 )
Promise 로 HTTP 통신을 하면 콜백 이벤트가 한번만 발생해서 (1회성), Subscribe 로 해줘야 한다.
- Promise 는 콜백 이벤트가 한번만 발생하고, Subscribe 는 콜백이벤트가 제한없이 발생해서 HTTP 통신으로 컴포넌트에 데이터에 넘겨줄때에는 Subscribe 로 넘겨주어야 한다.
앵귤러 HTTP 통신 처리과정. (Rx 패턴 사용)
Http통신을 완료하고, 컴포넌트에서 subscribe로 옵저버블 객체 이벤트를 구현할때, router.navigate 로 페이지를 이동시킬 수 있다.
openDeleteDialog():void{
const dialogRef = this.dialog.open(DeleteDialog, { width: '300px', disableClose: true })
.afterClosed()
.subscribe(result =>{
if(result = true){
// 다이얼로그 응답 결과가 true, 즉 삭제 확인 버튼을 눌렀으면
this.boardService.deleteBoard(this.postIdx).subscribe(data => { this.router.navigate(['/BoardList']) });
// 현재 idx 게시글 수정(state=0)을 API에 요청
// sbucribe() : HTTP 통신이 완료되면 navigate 메소드로 /boardList URL로 이동
}
});
보안 문제 등으로 http request url 에 header 를 붙여서 처리하고 싶으면 HttpHeaders 모듈 사용
Http 요청받으면 intercept -> 새로운 헤더를 붙여 복제 및 요청하는 방법 : HttpInterceptor
Promise 와 Observable 차이점
출저 및 참고 사이트 :
https://moaimoai.tistory.com/309
https://blog.briebug.com/blog/what-is-the-difference-between-promises-and-observables
공통점 :
- 둘다 비동기적인 함수를 동기화해서 사용할때 사용한다.
차이점 :
- Promise
- 하나의 값에 대해 resolve 하거나 reject 한다.
- 한번에 하나의 값에 대해서만 async 비동기 처리를 한다.
- 한번 완료된 async 값을 resolve 하고나면 더이상 사용이 불가능하고 취소를 할수 없다.
- Observable
-
다수의 비 동기적인 값들을 처리할 수 있다.
-
다수의 비 동기적인 값, 이벤트 스트림을 처리할때 사용한다.
-
많은 task나 value의 값들을 처리할 때 사용한다. 매 시간마다 pipe의 입구로 자동적으로 들어오는 값들을 처리할때 사용한다.
-
언제든지 값을 push 할수 있고, subscribe로 자동적으로 처리할 수 있다.
-
인풋값이 바뀌거나 특정시간마다 반복될 때 , 모든 자식 컴포넌트에게 값을 전달하고 싶을 때, 웹 소켓이 notification 을 푸시하고 싶을때 사용한다.
-
unsubscribe 를 사용하면 언제든지 이벤트 자동 등록을 취소할 수 있다.
-
가장 중요한 부분은 rx/js 의 오퍼레이터를 제공한다는 것이다.
-
map, filter, switchMap, combineLatest 의 오퍼레이터들을 pipe로 사용할 수 있고, subscribe를 하기전에 값을 transform 할수도 있다.
-
Promise 동작 방식
Observable 동작 방식
연속된 Observable 동작 방식
- Subscribe 에서 observable을 다른 Subscribe로 넘겨준다.
- Subject : 다른 subscribe에서 next 함수로 넘겨받은 observable