일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 2422번
- javascript
- 2503번
- 타입스크립트 프로그래밍
- 정리
- 17626번
- 5427번
- 한윤정이 이탈리아에 가서 아이스크림을 사먹는데
- 타입스크립트
- 나이트의이동
- 20300번
- 알고리즘
- 백준
- 1926번
- node.js
- 16953번
- 7526번
- 1541번
- 6593번
- 13913번
- 토마토
- 풀이
- 16439번
- 1969번
- 20365번
- 자바스크립트
- 5014번
- 123만들기
- 맥주마시면서걸어가기
- 14940번
Archives
- Today
- Total
Sqsung DevLog
<타입스크립트 프로그래밍> 8장: 비동기 프로그래밍, 동시성과 병렬성 정리 본문
8장: 비동기 프로그래밍, 동시성과 병렬성
- 유명한 자바스크립트 엔진(V8, SpinderMonkey)들은 태스크 멀티플렉싱 기법을 영리하게 이용하여, 스레드 하나로 비동기 작업을 처리하며, 이렇게 하나의 스레드로 비동기 작업을 처리하는 이벤트 루프가 바로 자바스크립트 엔진의 표준 모델이다
- 자바스크립트는 이벤트 루프 기반의 동시성 모델을 이용해 멀티스레드 기반 프로그래밍에서 공통적으로 나타나는 문제점을 해결한다 (동기화된 데이터 타입의 오버헤드, 뮤텍스, 세마포어 등)
- 타입스크립트를 이용하면 비동기 작업을 추적할 수 있으며, async/await 내장 기능을 이용해 비동기 프로그래밍을 동기 프로그래밍과 비슷한 관점에서 접근할 수 있다
- 또한, 멀티스레드 프로그램에서 엄격한 메시지 전달 프로토콜을 지정하도록 할 수 있다
8-1. 자바스크립트의 이벤트 루프
아래 코드의 경우 실행 순서는 'C -> A -> B'다.
// A. 첫 번째 setTimeout setTimeout(() => console.info('A'), 1); // B. 두 번째 setTimeout setTimeout(() => console.info('B'), 2); // C. 그냥 console.info console.info('C');
💡 예제 설명 1. setTimeout을 호출하면 콜백 참조와 1을 인수로 네이티브 타임아웃 API를 호출한다 2. setTimeout을 다시 호출하면 두 번째 콜백 참조와 2를 인수로 네이티브 타임아웃 API를 다시 호출한다 3. C를 콘솔에 출력한다 4. 백그라운드에서 1밀리초가 지난 다음 자바스크립트 플랫폼이 태스크를 이벤트 큐에 추가하여, 첫 번째 setTimeout에서 지정한 시간이 만료되었고 콜백을 호출할 수 있음을 알린다 5. 다시 1밀리초가 지난 다음 플랫폼이 두 번째 setTimeout의 콜백을 호출할 수 있도록 두 번째 태스크를 이벤트 큐에 추가한다 6. 콜 스택이 비었으므로 3번 과정을 완료한 플랫폼은 이벤트 큐에 태스크가 있는지 확인한다 7. 설정한 타임아웃이 모두 끝났고, 이벤트 큐와 콜 스택이 모두 비었다면 프로그램이 종료된다
8-2. 콜백 사용하기
- 비동기 자바스크립트 프로그래밍의 기본 단위는 콜백이다.
- 콜백은 평범한 함수이지만 다른 함수의 인수에 인수 형태로 전달될 뿐이다. 따라서 비동기 코드가 호출하는 콜백은 비동기로 호출됨을 알리는 전용 타입 시그니처가 없다
- 예를 들어 Node.js의
readFile
도 시그니처만 봐서는 비동기로 동작하며 readFile을 호출한 후 결과를 기다리지 않고 제어가 바로 다음 행으로 넘어간다는 사실을 알 수 없다 - 또한, 콜백 방식은 연달아 수행되는 작업을 코드로 표현하기 어렵다는 문제도 있다(그 유명한 콜백 지옥에 빠지게 된다)
8-3. 프로미스로 정상 회복하기
- 앞서 언급한 콜백의 단점을
Promise
로 해결할 수 있다function appendAndReadPromise(path: string, data: string): Promise<string> { return appendPromise(path, data) .then(() => readPromise(path)) .catch(error => console.error(error)); }
- 위 예제에서는 원하는 일을 완수하는 데 필요한 비동기 작업들을 직관적인 체인으로 묶었기 때문에 콜백 지옥에 빠질 일이 없다
8-4. async와 await
TS는
async/await
을 완벽히 지원하며 아주 강력한 타입 안전성을 제공한다프로미스가 필요한 곳에는 언제든 async/await을 사용할 수 있으며, async/await은 여러 동작을 연결된 여러 동작을 쉽게 이해하 수 있게 해주고, then을 여러번 사용할 필요가 없게 해준다
// Promise로 구현된 예제 function getUser() { getUserId(18) .then(user => getLocation(user)) .then(location => console.info('got location', location)) .catch(error => console.error(error)) .finally(() => console.info('done getting location')); } // async/await으로 구현된 예제 async function getUser() { try { let user = await getUserId(18); let location = await getLocation(user); console.info('got location', user); } catch (e) { console.error(e); } finally { console.info('done getting location'); } }
8-5. 비동기 스트림
- 여러 개의 데이터를 각각 밀에 다른 시점에 받게 되는 경우를 설계하기 위해 가장 흔히 Node.js의 Event Emitter, Rx.js 같은 리액티브 프로그래밍 라이브러리를 이용한다
- 두 방식의 차이는 콜백과 프로미스의 관계와 비슷하다. 이벤트는 빠르고 가벼운 반면, 리액티브 프로그래밍 라이브러리는 더 강력하며 이벤트 스트림을 조합하고 연결하는 기능을 제공한다
'TypeScript' 카테고리의 다른 글
<타입스크립트 프로그래밍> 10장: Namespace.Modules 정리 (0) | 2023.06.16 |
---|---|
<타입스크립트 프로그래밍> 9장: 프론트엔드 프레임워크와 백엔드 프레임워크 정리 (0) | 2023.06.16 |
타입스크립트 interface와 type의 차이점 정리 (0) | 2023.06.08 |
<타입스크립트 프로그래밍> 7장: 에러 처리 - 정리 (0) | 2023.06.05 |
<타입스크립트 프로그래밍> 6장: 고급 타입 - 정리 (0) | 2023.06.01 |