![Typescript 이해하기 - 제너레이터 이해하기](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FovhJ8%2FbtsATCjPaaU%2FoYxiE5TQ7xBFs7CD4rQb7K%2Fimg.png)
2023.11.26 - [백엔드/Typescript] - Typescript 컴파일 설정 - tsconfig.json
2023.11.26 - [백엔드/Typescript] - Typescript 변수 타입
2023.11.27 - [백엔드/Typescript] - Typescript 이해하기 - Promise 이해하기
필요 배경 지식
- TypeScript 변수 작성
- TypeScript Iterator 인터페이스
Prerequisite
- Typescript 컴파일 환경
제너레이터 문법
제너레이터 함수의 문법은 function * 으로 작성한다.
제너레이터 함수는 호출 중에 제너레이터 객체를 리턴한다.
제너레이터 객체는 iterator 인터페이스를 따라간다. (next, return 그리고 throw 함수가 있다.)
제너레이터 함수를 쓰는 두가지 주요 요인이 있다.
Lazy Iterators
제너레이터 함수를 이용하면 lazy iterators를 만들 수 있다.
예시는 다음과 같다.
다음 함수는 필요에 따라 infinite 숫자 목록을 반환한다.
function* infiniteSequence() {
var i = 0
while (true) {
yield i++
}
}
var iterator = infiniteSequence()
while (true) {
console.log(iterator.next()) // { value: xxxx, done: false } forever and ever
}
iterator가 끝나면 { done: true }
의 결과를 얻는것은 동일하다.
아래는 그 예시이다.
function* idMaker() {
let index = 0
while (index < 3) yield index++
}
let gen = idMaker()
console.log(gen.next()) // { value: 0, done: false }
console.log(gen.next()) // { value: 1, done: false }
console.log(gen.next()) // { value: 2, done: false }
console.log(gen.next()) // { done: true }
Externally Controlled Execution
제너레이터 함수는 기본적으로 함수가 실행을 일시중지하고 나머지 함수 실행을 호출자에게 전달할 수 있다.
yield
를 통해서 함수의 일시정지가 가능하다.
function* generator() {
console.log('Execution started')
yield 0
console.log('Execution resumed')
yield 1
console.log('Execution resumed')
}
var iterator = generator()
console.log('Starting iteration') // This will execute before anything in the generator function body executes
console.log(iterator.next()) // { value: 0, done: false }
console.log(iterator.next()) // { value: 1, done: false }
console.log(iterator.next()) // { value: undefined, done: true }
결과는 다음과 같다.
$ node outside.js
Starting iteration
Execution started
{ value: 0, done: false }
Execution resumed
{ value: 1, done: false }
Execution resumed
{ value: undefined, done: true }
제너레이터 규칙은 다음과 같이 정의할 수 있다.
- 제너레이터 함수를 시작하는 방법은 next를 이용해서 호출할 때 가능하다.
- 제너레이터 함수를 중지하는 방법은 yield를 이용해야한다.
- 제너레이터 함수를 다시 시작하려면 next를 호출해야한다.
- iterator.next(valueToInject)를 이용해서 yield 표현식의 결과 값을 제어할 수 있다.
- iterator.throw(error)를 이용해서 yield 표현식의 시점에서 예외처리를 할 수 있다.
iterator.next()의 예제는 다음과 같다.
function* generator() {
const bar = yield 'foo' // bar may be *any* type
console.log(bar) // bar!
}
const iterator = generator()
// Start execution till we get first yield value
const foo = iterator.next() // 여기서는 위에 정의되어있는 'foo'가 yield에 입력된다.
console.log(foo.value) // foo
// Resume execution injecting bar
const nextThing = iterator.next('bar') // 여기서는 next로 전달한 'bar'가 yield에 입력된다.
1. yield는 iterator의 next 함수에 전달된 매개변수를 반환한다.
2. 그리고 모든 이터레이터의 next 함수는 모든 유형의 매개변수를 허용한다.
3. 타입스크립트는 yield 연산자의 결과에 any 타입을 할당한다.
iterator.throw(error) 의 예제는 다음과 같다.
function* generator() {
try {
yield 'foo'
} catch (err) {
console.log(err.message) // bar!
}
}
var iterator = generator()
// 처음에 할당된 값인 foo를 가져온다.
var foo = iterator.next()
console.log(foo.value) // foo
// bar 에러를 주입했다.
var nextThing = iterator.throw(new Error('bar'))
위의 사항들을 종합적으로 요약하면 제너레이터는 다음과 같은 특징을 가지고 있다고 요약할 수 있다.
1. 제너레이터 함수는 yield를 통해 통신을 일시중지하고 외부에 제어를 맡길수 있다.
2. 외부에서 값을 제너레이터 함수 안으로 넣을 수 있다.
3. 외부에서 예외를 제너레이터 함수 안으로 던질 수 있다.
결론
- 제너레이터에 대해서 알아 보았다.
- Async Await을 이해하는데에 필요하다고 한다.
Reference
제네레이터 - TypeScript Deep Dive
yield는 이터레이터의 next함수에 전달된 매개변수를 반환하기 때문에 그리고 모든 이터레이터는 next함수는 모든 유형의 매개변수를 허용하고, 타입스크립트는 yield연산자의 결과에 any타입을 할
radlohead.gitbook.io
'백엔드 > NodeJS | Typescript' 카테고리의 다른 글
Typescript 프로젝트의 naming convention (0) | 2023.12.07 |
---|---|
Typescript 이해하기 - Async/Await 이해하기 (0) | 2023.11.28 |
Typescript 이해하기 - Promise 이해하기 (0) | 2023.11.27 |
Typescript 변수 타입 (0) | 2023.11.26 |
Typescript 컴파일 설정 - tsconfig.json (0) | 2023.11.26 |
개발 및 IT 관련 포스팅을 작성 하는 블로그입니다.
IT 기술 및 개인 개발에 대한 내용을 작성하는 블로그입니다. 많은 분들과 소통하며 의견을 나누고 싶습니다.