728x90
제네레이터와 async/await
제네레이터란?
코드 블록을 일시 중지했다가 필요한 시점에 재개할 수 있는 특수한 함수
-
함수 호출자에게 제어권 양도 가능
-
함수 호출자와 상태를 주고 받을 수 있음
제네레이터 함수의 정의
function*로 선언하고 하나 이상의 yield 표현식을 포함한다.
화살표 함수나 생성자 함수로 정의할 수 없음.
제네레이터 객체
제네레이터 함수가 반환한 객체는 이터러블이면서 이터레이터이다.
next 메서드를 갖는 이터레이터이지만 return, throw 메서드를 갖는다.
제네레이터의 일시중지와 재개
yield 키워드는 일시중지 시키거나 키워드 뒤에 오는 표현식의 평가 결과를 반환한다.
이터레이터의 next와 달리 인수 전달 가능
function* genFunc() {
// 처음 next 메서드를 호출하면 첫 번째 yield 표현식까지 실행되고 일시 중지된다.
// 이때 yield된 값 1은 next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티에 할당된다.
// x 변수에는 아직 아무것도 할당되지 않았다. x 변수의 값은 next 메서드가 두 번째 호출될 때 결정된다.
const x = yield 1;
// 두 번째 next 메서드를 호출할 때 전달한 인수 10은 첫 번째 yield 표현식을 할당받는
// x 변수에 할당된다. 즉, const x = yield 1;은 두 번째 next 메서드를 호출했을 때 완료된다.
// 두 번째 next 메서드를 호출하면 두 번째 yield 표현식까지 실행되고 일시 중지된다.
// 이때 yield된 값 x + 10은 next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티에 할당된다.
const y = yield (x + 10);
// 세 번째 next 메서드를 호출할 때 전달한 인수 20은 두 번째 yield 표현식을 할당받는 y 변수에 할당된다.
// 즉, const y = yield (x + 10);는 세 번째 next 메서드를 호출했을 때 완료된다.
// 세 번째 next 메서드를 호출하면 함수 끝까지 실행된다.
// 이때 제너레이터 함수의 반환값 x + y는 next 메서드가 반환한 이터레이터 리절트 객체의
// value 프로퍼티에 할당된다. 일반적으로 제너레이터의 반환값은 의미가 없다.
// 따라서 제너레이터에서는 값을 반환할 필요가 없고 return은 종료의 의미로만 사용해야 한다.
return x + y;
}
// 제너레이터 함수를 호출하면 제너레이터 객체를 반환한다.
// 이터러블이며 동시에 이터레이터인 제너레이터 객체는 next 메서드를 갖는다.
const generator = genFunc(0);
// 처음 호출하는 next 메서드에는 인수를 전달하지 않는다.
// 만약 처음 호출하는 next 메서드에 인수를 전달하면 무시된다.
// next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티에는 첫 번째 yield된 값 1이 할당된다.
let res = generator.next();
console.log(res); // {value: 1, done: false}
// next 메서드에 인수로 전달한 10은 genFunc 함수의 x 변수에 할당된다.
// next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티에는 두 번째 yield된 값 20이 할당된다.
res = generator.next(10);
console.log(res); // {value: 20, done: false}
// next 메서드에 인수로 전달한 20은 genFunc 함수의 y 변수에 할당된다.
// next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티에는 제너레이터 함수의 반환값 30이 할당된다.
res = generator.next(20);
console.log(res); // {value: 30, done: true}
제네레이터의 활용
이터러블 구현
// 무한 이터러블을 생성하는 제너레이터 함수
const infiniteFibonacci = (function* () {
let [pre, cur] = [0, 1];
while (true) {
[pre, cur] = [cur, pre + cur];
yield cur;
}
}());
// infiniteFibonacci는 무한 이터러블이다.
for (const num of infiniteFibonacci) {
if (num > 10000) break;
console.log(num); // 1 2 3 5 8...2584 4181 6765
}
async/await
await는 settled 상태가 되면 반환함.
'공부공부 > JS 딥다이브' 카테고리의 다른 글
[js 딥다이브] 48장 모듈 (0) | 2024.02.18 |
---|---|
[js 딥다이브] 47장 에러처리 (0) | 2024.02.18 |
[js 딥다이브] 45장 프로미스 (0) | 2024.02.18 |
[js 딥다이브] 44장 REST API (0) | 2024.02.18 |
[js 딥다이브] 43장 Ajax (0) | 2024.02.18 |