46장 제너레이터와 async/await
46.1 제너레이터란?
- 제너레이터 함수는 함수 호출자에게 함수 실행의 제어권을 양도할 수 있다.
- 제너레이터 함수는 함수 호출자와 함수의 상태를 주고받을 수 있다.
- 제너레이터 함수를 호출하면 제너레이터 객체를 반환한다.
46.2 제너레이터 함수의 정의
function*
키워드로 선언,yield
표현식 포함- 선언문, 표현식, 메서드, 클래스 메서드 형태
- 화살표 함수로 정의 불가
new
생성자로 호출 불가
46.3 제너레이터 객체
- 일반 함수: 호출 시 코드 블록 실행
- 제너레이터 함수: 호출 시 제너레이터 객체 생성 후 반환
- 제너레이터 객체는 이터러블이면서 동시에 이터레이터
Symbol.iterator
next
: 호출 시yield
까지 실행하고{ value, done }
객체 반환return
: 호출 시{ value, done: true }
반환 후 종료throw
: 호출 시 에러 발생
46.4 제너레이터의 일시 중지와 재개
yield
키워드로 실행 중지,next()
로 재개next(value)
: 값을 제너레이터 내부로 전달yield
연속 호출 구조:generator.next() -> yield -> generator.next() -> yield -> ... -> generator.next() -> return
46.5 제너레이터의 활용
- 이터러블의 구현
- 무한 이터러블 간결하게 생성 가능 (무한 피보나치 수열 등)
- 기존 이터레이션 프로토콜 구현보다 간단
- 비동기 처리
yield
표현식을 통해 비동기 흐름을 동기처럼 표현 가능- 제너레이터 실행기 필요 (co 라이브러리)
46.6 async/await
- async 함수
async
키워드로 정의, 항상 프로미스 반환- 명시적
return
없이도 암묵적으로 프로미스 resolve - 클래스의
constructor
메서드는 사용 불가
- await 키워드
await
: 프로미스가 완료될 때까지 대기- 반드시
async
함수 내부에서 사용
- 에러 처리
try...catch
문을 사용해 에러 처리 가능- 에러 전파 및 처리 명확
catch
문을 사용하지 않고 에러가 발생하면 reject된 프로미스 반환
47장 에러 처리
47.1 에러 처리의 필요성
- 에러 방치하면 프로그램 강제 종료
try...catch
문으로 적절히 대응하면 종료 없이 실행 가능- 예외 상황(DOM 조작 등)도 에러로 이어질 수 있으므로 방어 코드 필요
- null 체크,
?.
옵셔널 체이닝 사용 등
- null 체크,
47.2 try...catch...finally 문
try
,catch
,finally
세 블록으로 구성try
: 실행할 코드catch
: 에러 발생 시 실행, 에러 객체가 인자로 전달finally
: 에러 발생과 상관 없이 무조건 실행
catch
생략 불가,finally
생략 가능
47.3 Error 객체
Error
생성자 함수로 에러 객체 생성 가능const error = new Error('invalid');
message
: 전달된 에러 메시지stack
: 콜스택 정보 (디버깅 목적)
생성자 함수 | 인스턴스 |
---|---|
Error |
일반적인 에러 |
SyntaxError |
문법 오류 |
ReferenceError |
정의되지 않은 변수 참조 |
TypeError |
타입 불일치 |
RangeError |
허용 범위를 벗어난 값 |
URIError |
URI 처리 함수 오류 |
EvalError |
eval 함수 오류 |
47.4 throw 문
- 에러 객체 생성만으로는 에러가 발생하지 않음
throw
문으로 명시적 에러 발생 가능throw
:catch
블록 실행 트리거
47.5 에러의 전파
- 콜 스택을 따라 호출자 방향(아래 방향)으로 전파
- catch되지 않으면 프로그램 강제 종료
setTimeout
,Promise.then
등 비동기 콜백 함수 내부에서 throw한 에러는 전파되지 않음- 전역에서 uncaught되어 종료될 수 있음, 내부에서
try/catch
로 직접 처리 필요
- 전역에서 uncaught되어 종료될 수 있음, 내부에서
- 에러는 호출자 쪽에서만 처리 가능, 적절한 위치에
catch
구문 필요
48장 모듈
48.1 모듈의 일반적 의미
- 모듈: 재사용 가능한 코드 조각, 일반적으로 기능 단위로 파일 분리
- 자신만의 파일 스코프(모듈 스코프)를 가지며, 내부 자산은 기본적으로 비공개
export
키워드로 선택적 공개 가능import
를 통해export
된 자산 재사용 가능
48.2 자바스크립트와 모듈
- 과거 자바스크립트는 파일 스코프 없이 전역 공유, 모듈 시스템 미지원
- 여러
script
태그를 사용해도 전역 스코프 공유, 변수 충돌 가능성 - 문제 해결을 위해 CommonJS(Node.js 기반), AMD 방식 등장
48.3 ES6 모듈(ESM)
type = "module"
속성을 가진<script>
태그로 ESM 로드- ESM: 기본적으로 strict mode 적용
- 모듈 스코프
- ESM 내부 변수는 전역 스코프에 등록되지 않음
- 동일한 식별자를 다른 모듈에서 선언해도 충돌 없이 동작
- 외부 모듈에서 ESM 내 식별자에 접근 불가 ->
export
필요
export
키워드- 변수, 함수, 클래스 등을 외부에 공개 가능
- 선언 앞에 export 키워드 사용
export const pi = Math.PI; export function square(x) { return x * x; }
- 하단에서 객체처럼 한 번에 export
const pi= Math.PI; function square(x) { return x * x; } export { pi, square };
import
키워드- 다른 모듈이 export한 식별자를 현재 모듈 스코프 내부로 불러오기
- 기본 사용
import { pi, square } from './lib.mjs';
- 전체 import (
as
구문) import * as lib from './lib.mjs'; lib.square(2);
- 이름 변경 후 import (
as
구문) import { square as sq } from './lib.mjs'; sq(2);
default
export- 모듈에서 하나의 값만 export할 때 사용
- 이름 없이 export, import 시 임의의 이름 사용
// lib.mjs export default x => x * x;
// app.mjs
import square from './lib.mjs';
square(3); // 9
```
49장 Babel과 Webpack을 이용한 ES6+/ES.NEXT 개발 환경 구축
49.1 Babel
- Babel: ES6+/ES.NEXT 코드를 ES5 코드로 변환하여 구형 브라우저 호환성 확보
- 브라우저가 지원하지 않는 최신 문법 자동 변환
- 화살표 함수, 지수 연산자 등
- 브라우저에서
require
함수 미지원- Babel은 기본적으로 CommonJS 방식으로 트랜스파일링 (
require
,exports
) - 브라우저는 이를 지원하지 않으므로 브라우저 실행 시 에러 발생
- Babel은 기본적으로 CommonJS 방식으로 트랜스파일링 (
49.2 Webpack
- Webpack: 여러 JS 모듈, 이미지, CSS 등을 하나의 번들 파일로 묶음
- 모듈 로더 없이 브라우저에서 실행 가능
- Babel과 함께 사용하여 트랜스파일링 + 번들링
'Study > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
[모던 자바스크립트 Deep Dive] 40장 ~ 45장 (0) | 2025.05.11 |
---|---|
[모던 자바스크립트 Deep Dive] 36장 ~ 40장 (0) | 2025.05.11 |
[모던 자바스크립트 Deep Dive] 31, 32, 35장 (0) | 2025.04.10 |
[모던 자바스크립트 Deep Dive] 26장 ~ 30장 (0) | 2025.04.03 |
[모던 자바스크립트 Deep Dive] 21장 ~ 25장 (0) | 2025.03.27 |