타입스크립트 - 비동기 처리

HTTP 요청은 비동기이므로 콜백 헬과 같은 중첩 스코프를 만들어 냅니다. 타입스크립트는 ES6에서 제안된 프로미스를 이용해 콜백 헬이 되지 않도록
제어 흐름을 개선할 수 있습니다.
자바스크립트는 비동기 요청 후 응답 결과를 콜백 함수로 처리합니다. 이렇게 콜백 함수로 처리하는 상황은 대체로 응답 시점을 예측할 수 없을 때입니다.
이와 같은 상황의 예로 HTTP 요청에 대한 응답 처리나 파일 I/O 작업 등이 있습니다. 비동기 요청 후 응답 결과는 콜백 함수의 매개변수를 통해 전달됩니다.

스코프가 깊어지게 되면 콜백 함수와 제어문 사용으로 스코프가 중첩돼 가독성이 안좋습니다.

프로미스 소개와 동작 과정

프로미스(promise)는 중첩 스코프 문제를 해결하기 위해 ES6에서 제한된 객체입니다. 프로미스는 스코프가 깊어지지 않도록 나열식 패턴 방식으로 입력 데이터를 처리할 수 있게 합니다.

프로미스는 다음과 같은 세가지 상태가 존재합니다.

  • 대기 상태 (pending)
  • 충족 상태 (fulfilled)
  • 거부 상태 (rejected)

대기 상태는 프로미스가 실행되고 값이 결정되지 않은 상태를 말합니다. 충족 상태는 대기 상태가 끝난 뒤 값이 결정된 상태이며 resolve 함수를 통해 값을 전달합니다.
거부 상태는 프로미스가 제대로 처리되지 않고 거부된 상태로 catch 메서드를 통해 예외 처리해 주어야 합니다.

프로미스는 최초 실행 함수(executor)를 통해 실행됩니다. 실행 함수가 시작되고 마치기전까지 대기 상태를 유지합니다.
프로미스는 익명 함수 형태로 작성 할수 있습니다.

1
2
3
const promise = new Promise((resolve, rejects) => {
// 처리할 프로미스 작업 로직
})

프로미스가 정상으로 수행됐다면 충족 상태가 되어 resolve 함수를 호출, 반대로 실패했다면 거부 상태가 되어 reject 함수를 호출해 예외 처리를 진행 합니다.

1
2
3
4
5
6
7
const promise = new Promise((resolve, rejects) => {
if(충족 상태){
resolve(result);
} else {
rejects('거절사유');
}
})

첫번째 매개변수로 전달된 resolve 함수를 호출하면 then 메서드가 호출됩니다. then 메서드는 결정된 값에 대해 후속 처리를 담당합니다.
reject 함수에 거절된 사유를 전달하며 catch 메서드는 전달된 이유를 표시해주고 예외 처리를 진행합니다.

프로미스를 사용한 중첩 스코프 개선

then 메서드를 이용해 중첩 코드 개선

then 메서드는 하나의 처리 작업에 해당하며 작업 개수에 따라 체이닝 형태로 여러 개를 동시에 선언할 수 있습니다.
오류가 있다면 reject 를 호출 할 때 거부 이유를 함께 전달함으로써 catch 메서드를 통해 예외 상황을 처리할 수 있도록 합니다.
then 메서드를 체이닝 형태로 선언하고 then 메서드에서 발생한 예외 상황을 처리하려면 catch 메서드를 마지막에 선언해야 합니다.

임의 시간만큼의 지연이 있는 비동기 함수 여러 개를 동시에 호출하면 호출 순서와 응답 결과의 순서가 일치되지 않는 문제가 있습니다.
Promise.all() 메서드는 비동기 응답을 호출 순서에 따라 처리할 수 있는 인터페이스를 제공합니다.
이 때 Promise.all()는 작업 완료 시점이 일정치 않아 뒤바뀐 결정 갑의 순서를 호출 순서에 따라 출력해주는 역할을 합니다.

반응형 프로그래밍

반응형 프로그래밍 모델은 웹 페이지에 들어오는 스트림 형태의 입력 이벤트를 감지해 반응을 처리할 수 있는 모델입니다.
이와 관련한 예로 입력에 반응하는 검색어 제안 기능이 있습니다. 검색어 제안 기능은 사용자가 어떠한 단어를 입력하면 단어에 연관된 키워드를 보이는 기능입니다.

발행 구독 패턴

시스템은 기본적으로 사용자의 입력에 대해 반응하고 적절한 처리를 해 줄 수 있어야 합니다. 이벤트는 특정 시간에 발생하지 않고 사용자가 의도한 시점에 발생합니다.
반응형 프로그래밍은 입력 이벤트를 감지하고 처리하는 데 발행 구독 패턴을 이용합니다.
발행 구독 패턴에서 옵저버는 옵저버블을 관찰하고, 옵저버블은 상태가 변경됐을 때 옵저버에게 상태가 변경됐음을 통지해 줍니다.
여기서 관측 대상인 옵저버블은 사용자가 입력한 데이터 스트림입니다. 사용자 입력 이벤트는 옵저버가 감시하고 처리해야 할 대상입니다.
옵저버는 옵저버블을 구독하고 있다가 옵저버블의 상태가 변경되면 옵저버블로부터 상태가 변경됐음을 통지받습니다.

RxJS

RxJS는 데이터 스트림에 대한 연산을 연산자 메서드를 이용해 연쇄적으로 처리할 수 있게 관련 인터페이스를 제공합니다.
RxJS에서는 사용자가 키를 입력할 대마다 데이터가 생성되고 생성된 데이터는 연산자에 의해 데이터가 처리되고 나서 구독될지 말지를 결정합니다.
RxJS에서 스트림 데이터를 처리하기 위해 세 단계를 거칩니다.
데이터 생성단계에서는 데이터 생성자가 스트림 데이터를 생성합니다. 데이터 처리 단계에서는 스트림 데이터가 파이프 형태로 연결된 연산자를 통과하면서 차례대로 처리됩니다.
데이터 소비 단계에서는 구독자가 데이터 스트림을 받아 최종적인 처리를 수행함으로써 데이터를 소비합니다.

동시성(concurrency)과 동기화(synchronous) 작업

동시성란 멀티 스레드와 같이 여러 개의 단위 작업이 동시에 실행되는 성질을 말합니다. 자바스크립트에서 동시성은 작업을 동시에 처리하는 것을 의미합니다.

  • 비동기 프로그래밍 모델
  • 멀티 스레드 프로그래밍

비동기 프로그래밍 모델은 HTTP 요청과 같은 비동기 요청상황에 해당하는 모델입니다. 비동기 프로그래밍 모델은 동기 프로그래밍 모델과 달리,
단위 작업을 하나의 스레드내에서 번갈아 가며 실행합니다. 여기서 스레드는 프로세스보다 작은 단위로 프로세스 내에 존재하는 작은 작업 단위를 의미합니다.

멀티 스레드 프로그래밍은 멀티 코어 기기상에서 여러 스레드에서 작업을 동시에 실행하는 방식입니다. 여러 작업을 동시에 실행하기 때문에 병렬성의 특정이 있습니다.
멑티 스레드는 자바스크립트에서 지원하지 않습니다. 지원하지 않는 이류는 싱글 스레드만으로 실행 해야 페이지를 로딩할 때 보다 더 빠른 속도로 실행할 수 있게 때문입니다.

더 근본적인 이유로는 브라우저의 인터프리터가 단일 스레드여서 멀티 스레드를 지원하지 않기 때문, 때론 setTimeout 함수를 통한 타이머 호출은 마치 멀티 스레드 처럼
동작하는 것처럼 보이지만 실은 멀티 스레드가 아닌 싱글 스레드에서 실행됩니다.
비동기 프로그래밍은 작업을 수차적으로 실행 하지 않고 응답 시간을 고려해 실행 순서가 결정됩니다. 동기화 실행이 되면 중간에 비동기 작업이 있더라고 호출순서에 따라 작업이 실행 됩니다.

Async/Await

Async/Await 는 ES2015애 제안됐고 타입스크립트에서는 1.7에서 추가됐습니다.
Async/Await 를 이용하며 비동기 함수를 동기화 할 수 있습니다.

비동기 호출 코드

비동기 호출은 응답 시간이 저마다 다를 수 있으므로 차례대로 실행되지 않고 호출 시간과 응답 시간을 고려해 동작을 수행합니다.
반대로 동기화 코드는 순서가 보장되며 순서대로 실행됩니다. 비동키 코드를 동기화한다면 비동기 코드를 여럿 사용하는 경우 코드 제어가 간소화 됩니다.

1
2
3
async  function hello() {
await run();
}

호출 하는 함수는 프로미스 구문을 포함해 비동기 처리를 수행해야 합니다 .

댓글

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×