티스토리 뷰
코루틴에서 제너레이터, 이터러블/이터레이터까지 여정
1. 코루틴?
코루틴(coroutine)을 알기 위해서는 루틴(routine)에 대한 이해가 먼저 필요하다. 루틴은 우리가 잘 알고 있는 function()
을 생각하면 된다.
루틴(Routine)
- 한 번 입장하면 무조건 반환된다.
- 반복적으로 사용할 수 있다.
- 인자를 받아들여 내부 로직에 활용할 수 있다.
코루틴(Coroutine)
- 여러번 진입할 수 있고 여러번 반환할 수 있다.
- 특수한 반환을 통해 그 다음 진입을 지정할 수 있다.
특징
- 동기명령을 일시적으로 멈춘다. ->
suspend
- 다시 진입해서 그 다음부터 실행한다. ->
resume
루틴에서 명령은 적재되면 한 번에 다 실행된다. 하지만 코루틴은 중간에 멈출 수도 재개할 수도 있다. 루틴과 코루틴의 가장 큰 차이다.
2. 제너레이터
제너레이터는 이터러블을 생성하는 함수이며 실행을 중간에 멈췄다가 필요한 시점에 재개할 수 있는 기능(코루틴의 특징)을 가진다.
참고 : 제너레이터는 코루틴의 특징을 가졌기 때문에
제너레이터 = 코루틴
이라고 생각할 수 있다. 하지만 제너레이터는 코루틴의 일종이지 코루틴은 아니다. 코루틴은 반환시 다음 진입점을 지정할 수 있어야 하는데 제너레이터는 다음 yield로 이동하지, 진입지점을 맘대로 정할 수는 없기 때문이다. 그래서 제너레이터는 세미 코루틴이라고 한다. 자세한 설명은 위키와 이 글에 정리가 잘 되어 있다.
사용법
function* gen() {
yield 1;
yield 2;
yield 3;
}
const g = gen(); // 제너레이터 객체가 반환된다.
- 제너레이터 함수는
function*
키워드로 선언한다. - 하나 이상의
yield
문을 포함한다.yield
에서 메서드의 실행을 멈출 수 있다.
- 제너레이터 함수를 호출하면 제너레이터 객체가 반환된다.
g.next(); // {value: 1, done:false}
g.next(); // {value: 2, done:false}
g.next(); // {value: 3, done:false}
g.next(); // {value: undefined, done:true}
- 제너레이터 객체의
next()
를 호출하면 처음 만나는yield
문까지 실행되고 일시 중단(suspend
)된다. - 또다시
next()
를 호출하면 중단된 위치에서 다시 실행(resume
)되어 다음에 만나는yield
문까지 실행되고 일시 중단(suspend
)된다.
활용 - 무한 이터러블
const infinity = (functon*() {
let i = 0;
while(true) yield i++;
})();
console.log(infinity.next());
console.log(infinity.next());
피보나치
function* fibonacci() {
let current = 0;
let next = 1;
while (true) {
let reset = yield current;
[current, next] = [next, next + current];
if (reset) {
current = 0;
next = 1;
}
}
}
const sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next(true).value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
3. 이터러블과 이터레이터
Generator는 iterable이면서 동시에 iterator인 객체다. 그래서 Symbol.iterator 메서드로 이터레이터를 별도로 생성할 필요가 없다.
Iterable
- iterable protocol의 구현체
- iterable은 iteration의 행동을 정의한다.
- Symbol.iterator 메서드가 있다.
- Symbol.iterator는 iterator를 반환해야 한다.
Iterator
- iterator protocol의 구현체
next()
메서드를 가진다.next()
는 이터러블을 순회하며value
와done
속성을 가진 객체를 반환한다.- 작업이 끝나면 done은 true가 된다.
Iteration protocol
데이터 컬렉션을 순회하기 위한 프로토콜이다. 이터레이션 프로토콜에는 이터러블 프로토콜(iterable protocol)
과 이터레이터 프로토콜(iterator protocol)
이 있다.
- 이터레이션 프로토콜을 준수한다는 것은
Symbol.iterator
메서드를 가지고 있다는 것이다. Symbol.iterator
메서드는iterator
를 반환한다. (이터러블 프로토콜)iterator
는next
메서드로iterable
을 순회하며value
와done
속성을 가진 객체를 반환한다. (이터레이터 프로토콜)
const gen = {
// iterable
[Symbol.iterator]() {
const arr = [1,2,3,4];
let cursor = 0;
return {
// iterator
next() {
return {done:cursor >= arr.length, value:cursor < arr.length ? arr[cursor++] : undefined };
}
};
}
};
const iter1 = gen[Symbol.iterator]();
const iter2 = gen[Symbol.iterator]();
위 코드에서 구현한 gen
은 이터러블이면서 이터레이터인 객체다.
참고자료
- 코드스피츠 89 - Programmng 101 5회차
- 코드스피츠 89 - Programmng 101 6회차
- 제너레이터와 async/await
- 이터레이션과 for ...of문
- Iterators and generators
- ES6의 제너레이터를 사용한 비동기 프로그래밍
'Js' 카테고리의 다른 글
[js] 정규표현식(Regular Expression) (0) | 2021.05.16 |
---|---|
[js] 특정 날짜에 해당하는 Date 객체 생성 및 날짜 가져오기 (0) | 2019.08.25 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- MPEG-2 TS
- github actions components
- HtmlUtils
- getPath
- github actions 기초
- FileNameFilter
- Best Time to Buy and Sell Stock
- getAbsolutePath와
- csv to bean
- csv 라이브러리
- AOP
- 그런RESTAPI로괜찮은가
- 정규경로
- opencsv
- 특수문자 치환
- sockjs
- websocket handshake
- 정규표현식 플래그
- java8 stream
- 다이나믹프록시
- self-descriptive
- getCanonicalPath
- file
- hls.js
- github actions 구성요소
- 문자열인코딩과 문자집합의 차이
- 정규표현식 패턴
- 코프링
- Longest Consecutive Sequence
- CGLIB프록시
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함