타입스크립트의 제너레이터 함수

타입스크립트의 제너레이터 함수

이 글은 타입스크립트의 제너레이터 함수에 대해 설명합니다.

코드 샘플과 함께 제너레이터 함수 사용의 기초부터 비동기 처리와 결합된 고급 예제까지 모두 배울 수 있습니다.

YouTube Video

제너레이터 함수

타입스크립트의 제너레이터 함수는 자바스크립트의 제너레이터 함수와 유사한 기능을 제공합니다. 제너레이터 함수는 function*(별표가 붙은 함수 선언)을 사용하여 정의되며, 일반 함수와는 달리 실행을 중지하고 다시 시작할 수 있는 특수한 함수입니다.

제너레이터 함수가 호출되면 이터레이터가 반환되며, 이 이터레이터를 통해 값을 하나씩 생성하고, yield 키워드를 사용하여 실행을 중지하거나 외부에서 값을 보낼 수 있습니다.

제너레이터 함수의 기본 문법

 1function* myGenerator(): Generator<number, void, unknown> {
 2    yield 1;
 3    yield 2;
 4    yield 3;
 5}
 6
 7const gen = myGenerator();
 8
 9console.log(gen.next().value); // 1
10console.log(gen.next().value); // 2
11console.log(gen.next().value); // 3
12console.log(gen.next().done);  // true (Iteration finished)
  • function* myGenerator()로 제너레이터 함수를 정의합니다.
  • yield 키워드는 값을 반환하면서 함수 실행을 중지합니다.
  • next() 메서드가 호출될 때마다 제너레이터 함수의 실행이 재개되어 다음 yield로 진행됩니다.

next()는 다음 값과 done 속성을 포함하는 객체를 반환합니다. donetrue이면 모든 값이 생성되었고 제너레이터의 처리가 완료되었음을 나타냅니다.

제너레이터 함수의 활용

제너레이터 함수를 사용하면 순차적 처리를 쉽게 표현할 수 있습니다. 다음 예제에서는 숫자 시퀀스를 생성하는 제너레이터 함수를 만듭니다.

 1function* sequenceGenerator(start: number = 0, step: number = 1) {
 2    let current = start;
 3    while (true) {
 4        yield current;
 5        current += step;
 6    }
 7}
 8
 9const seq = sequenceGenerator(1, 2);
10
11console.log(seq.next().value); // 1
12console.log(seq.next().value); // 3
13console.log(seq.next().value); // 5
  • 이 예제에서 sequenceGenerator는 무한히 증가하는 숫자 시퀀스를 생성합니다. yield를 사용해 각 단계에서 값을 반환하고, 이후 호출에서는 다음 값을 생성합니다.

next에 값 전달하기

next() 메서드는 값을 받을 수 있으며, 이 값은 제너레이터 함수에 전달될 수 있습니다.

 1function* adder() {
 2    const num1 = yield;
 3    const num2 = yield;
 4    yield num1 + num2;
 5}
 6
 7const addGen = adder();
 8addGen.next();          // Initialization
 9addGen.next(5);         // Set 5 to num1
10const result = addGen.next(10).value; // Set 10 to num2 and get result
11console.log(result);    // 15
  • 이 예제에서 next(5)next(10)은 각각의 값을 제너레이터 함수에 전달하며, yield num1 + num2는 이 값들의 합을 반환합니다.

returnthrow

  • return(value)는 제너레이터를 종료하고 지정된 값을 반환할 수 있습니다.
  • throw(error)는 제너레이터 내부에서 예외를 발생시킬 수 있으며, 제너레이터 내에서 예외 처리를 위해 사용됩니다.
 1function* testGenerator() {
 2    try {
 3        yield 1;
 4        yield 2;
 5    } catch (e) {
 6        console.error("Error caught:", e);
 7    }
 8}
 9
10const gen = testGenerator();
11console.log(gen.next().value); // 1
12gen.throw(new Error("An error occurred!")); // Error caught: An error occurred!
  • 이 예제에서 throw 메서드는 제너레이터 내부에서 오류를 발생시키며, 이 오류는 제너레이터 내부에서 포착됩니다.

TypeScript에서의 타입 정의

제너레이터 함수의 타입 정의는 다음 형식으로 지정할 수 있습니다.

1// Generator<YieldType, ReturnType, NextType>
2function* myGenerator(): Generator<number, void, unknown> {
3    yield 1;
4    yield 2;
5    yield 3;
6}
  • Generator<YieldType, ReturnType, NextType> 형식으로 타입을 지정합니다.
    • YieldType은(는) yield에 의해 반환된 값의 타입입니다.
    • ReturnType은(는) return에 의해 반환된 값의 타입입니다.
    • NextType은(는) next()에 전달된 값의 타입입니다.

다음 예에서는 타입을 사용하여 제너레이터를 안전하게 사용하는 구체적인 타입이 지정됩니다.

 1function* numberGenerator(): Generator<number, void, number> {
 2    const num1 = yield 1;
 3    const num2 = yield num1 + 2;
 4    yield num2 + 3;
 5}
 6
 7const gen = numberGenerator();
 8
 9console.log(gen.next().value);   // 1
10console.log(gen.next(10).value); // 12 (10 + 2)
11console.log(gen.next(20).value); // 23 (20 + 3)

제너레이터와 비동기 처리

제너레이터는 비동기 처리에도 활용할 수 있습니다. 예를 들어, yield를 사용하여 비동기 작업의 결과를 기다리면서 순차적으로 처리할 수 있습니다. 그러나 TypeScript나 JavaScript에서는 async/await가 더 일반적으로 사용됩니다.

1function* asyncTask() {
2    const result1 = yield fetch("https://codesparklab.com/json/example1.json");
3    console.log(result1);
4
5    const result2 = yield fetch("https://codesparklab.com/json/example2.json");
6    console.log(result2);
7}

따라서 제너레이터를 사용해 비동기 작업을 순차적으로 처리할 수는 있지만, Promise와 async/await가 더 편리하기 때문에 비동기 처리에서는 일반적으로 사용되지 않습니다.

요약

  • 제너레이터 함수function*으로 정의되며, 실행을 멈추고 yield를 통해 값을 반환할 수 있는 특별한 함수입니다.
  • **next()**를 사용하여 제너레이터 실행을 다시 시작하고 값을 받을 수 있습니다. 또한, next(value)를 사용하여 제너레이터에 값을 보낼 수 있습니다.
  • **return()**과 **throw()**를 사용하여 제너레이터 함수를 종료하거나 오류를 처리할 수 있습니다.
  • TypeScript에서 제너레이터를 사용할 때, 타입 정의를 활용하여 타입 안전한 코드를 작성할 수 있습니다.

제너레이터는 반복을 유연하게 제어할 수 있는 강력한 도구입니다.

위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.

YouTube Video