Jieunny์ ๋ธ๋ก๊ทธ
[TS] ๋ฐ๋ณต๊ธฐ์ ์์ฑ๊ธฐ ๋ณธ๋ฌธ
๐ฃ ๋ฐ๋ณต๊ธฐ ์ดํดํ๊ธฐ
โ๏ธ tsconfig.json์์ downlevelIteration ํญ๋ชฉ์ true๋ก ์ค์ ํด์ผ ๋ฐ๋ณต๊ธฐ๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋ค.
๐ ๋ฐ๋ณต๊ธฐ์ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์
โฐ for...of ๊ตฌ๋ฌธ์ ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์๋ '๋ฐ๋ณต๊ธฐ'๋ผ๋ ์ฃผ์ ๋ก ์ฐพ์๋ณผ ์ ์๋ค.
โฐ ๋ฐ๋ณต๊ธฐ๋ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์๋ ๊ฐ์ฒด์ด๋ค.
๏น next๋ผ๋ ์ด๋ฆ์ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
๏น next ๋ฉ์๋๋ value์ done์ด๋ผ๋ ๋ ๊ฐ์ ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
// ๋ฐ๋ณต๊ธฐ ์ ๊ณต์
export const createRangeIterable = (from: number, to: number) => {
let currentValue = from
return {
next() {
const value = currentValue < to ? currentValue++ : undefined
const dome = value == undefined
return {value, done}
}
}
}
โฐ createRangeIterable ํจ์๋ next ๋ฉ์๋๊ฐ ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฏ๋ก ๋ฐ๋ณต๊ธฐ๋ฅผ ์ ๊ณตํ๋ ์ญํ ์ ํ๋ค.
โฐ ๋ฐ๋ณต๊ธฐ๋ฅผ ์ ๊ณตํ๋ ์ญํ ์ ํ๋ ํจ์๋ฅผ '๋ฐ๋ณต๊ธฐ ์ ๊ณต์(iterable)' ๋ผ๊ณ ํ๋ค.
import {createRangeIterable} fromo './createRangeIterable'
const iterator = createRangeIterable(1, 3+1) // ๋ฐ๋ณต๊ธฐ๋ ํ์ฌ ๋์ํ์ง ์๋๋ค.
while(true) {
const {value, done} = iterator.next() // ๋ฐ๋ณต๊ธฐ๋ฅผ ๋์์ํค๋ค.
if(done) break
console.log(value) // 1 2 3
}
โฐ createRangeIterable ํจ์๋ฅผ ํธ์ถํด์ ๋ฐ๋ณต๊ธฐ๋ฅผ iterator ๋ณ์์ ์ ์ฅํ๋ค.
โฐ ๋ฐ๋ณต๊ธฐ๋ ์์ฒ๋ผ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์๋ฅผ ํธ์ถํด์ผ ์ป์ ์ ์๋ค.
โฐ ์ฌ์ฉ์๊ฐ for...of ๊ตฌ๋ฌธ์ ์์ฑํ๋ฉด TSC ์ปดํ์ผ๋ฌ๋ ์ด์ฒ๋ผ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์์ ๋ฐ๋ณต๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ก ๋ฐ๊ฟ์ค๋ค.
๐ ๋ฐ๋ณต๊ธฐ๋ ์ ํ์ํ๊ฐ?
โฐ range ํจ์๋ ๋น๊ตํ์ ๋, range ํจ์๋ ๊ฐ์ด ํ์ํ ์์ ๋ณด๋ค ์ด์ ์ ๋ฏธ๋ฆฌ ์์ฑํ๋ค.
โฐ ๋ฐ๋ณต๊ธฐ๋ ๊ฐ์ด ํ์ํ ์์ ์ ๋น๋ก์ ์์ฑํ๋ค.
โฐ ๊ฒฐ๊ณผ์ ์ผ๋ก ์์คํ ๋ฉ๋ชจ๋ฆฌ์ ํจ์จ์ฑ ๊ด์ ์์ ๋ณด๋ฉด ๋ฐ๋ณต๊ธฐ๊ฐ ํจ์ฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๊ฒ ์๋ชจํ๋ค.
๐ for...of ๊ตฌ๋ฌธ๊ณผ [Symbol.iterator] ๋ฉ์๋
โฐ range ํจ์๋ for...of ๊ตฌ๋ฌธ์ of ๋ค์ ์ฌ ์ ์๋ค.
import {range} from './range'
for(let value of range(1, 3+1))
console.log(value)
โฐ ํ์ง๋ง ๋ฐ๋ณต๊ธฐ๋ฅผ of ๋ค์ ์ ์ฉํ๋ฉด '[Symbol.iterator]() ๋ฉ์๋๊ฐ ์๋ค' ๋ผ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
import {createRangeIterable} from './createRangeIterable'
const iterable = createRangeIterable(1, 3+1)
for(let value of iterable)
// ์ค๋ฅ
console.log(value)
โฐ ์ด ์ค๋ฅ๋ createRangeIterable ํจ์๋ฅผ ํด๋์ค๋ก ๊ตฌํํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
โฐ ํด๋์ค๋ for...of ๊ตฌ๋ฌธ์ of ๋ค์ ์ฌ ์ ์๋ค.
export class RangeIterable {
constructor(public from: number, public to: number) {}
[Symbol.iterator]() {
const that = this
let currentValue = that.from
return {
next() {
const value = currentValue < that.to ? currentValue++ : undefined
const done = value == undefined
return {value, done}
}
}
}
}
โฐ ํด๋์ค์ ๋ฉ์๋๋ function ํค์๋๊ฐ ์๋ต๋์์ ๋ฟ function ํค์๋๋ก ๋ง๋ค์ด์ง๋ ํจ์์ด๋ค.
โฐ function ํค์๋๋ก ๋ง๋ค์ด์ง ํจ์๋ ๋ด๋ถ์์ this ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
โฐ 4ํ์ this๋ RangeIterable ํจ์๋ฅผ ๋ด๊ณ ์๋๋ฐ, next ํจ์ ๋ํ function ํค์๋๊ฐ ์๋ต๋ ๋ฉ์๋์ด๋ฏ๋ก ์ปดํ์ผ๋ฌ๊ฐ next์ this๋ก ํด์ํ์ง ์๊ฒ ํ๋ ์ฝ๋ ํธ๋ฆญ์ด๋ค.
๐ Iterable<T>์ Iterator<T> ์ธํฐํ์ด์ค
โฐ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์์ Iterable<T>์ Iterator<T> ์ ๋ค๋ฆญ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
1๏ธโฃ Iterable<T>
class ๊ตฌํ ํด๋์ค implements Iterable<์์ฑํ ๊ฐ์ ํ์
> {}
โฐ ์์ ์ ๊ตฌํํ๋ ํด๋์ค๊ฐ [Symbol.iterator] ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค๋ ๊ฒ์ ๋ช ํํ๊ฒ ์๋ ค์ฃผ๋ ์ญํ
2๏ธโฃ Iterator<T>
[Symbol.iterator](): Iterator<์์ฑํ ๊ฐ์ ํ์
> {}
โฐ ๋ฐ๋ณต๊ธฐ๊ฐ ์์ฑํ ๊ฐ์ ํ์ ์ ๋ช ํํ๊ฒ ์๋ ค์ค๋ค.
export class StringIterable implements Iterable<string> {
constructor(private strings: string[] = [], private currentIndex: number = 0) }{}
[Symbol.iterator](): Iterator<string> {
const that = this
let currentIndex = that.currentIndex, length = that.strings.length
const iterator: Iterator<string> = {
next(): {value: string, done: boolean} {
const value = currentValue < length ? that.strings[currentIndex++] : undefined
const done = value == undefined
return {value, done}
}
}
return iterator
}
}
๐ฃ ์์ฑ๊ธฐ ์ดํดํ๊ธฐ
โ๏ธ ESNext JS์ ํ์ ์คํฌ๋ฆฝํธ๋ yield๋ผ๋ ํค์๋๋ฅผ ์ ๊ณตํ๋ค.
โฐ yield๋ return ํค์๋์ฒ๋ผ ๊ฐ์ ๋ฐํํ๋ค.
โฐ yield๋ ๋ฐ๋์ function* ํค์๋๋ฅผ ์ฌ์ฉํ ํจ์์์๋ง ํธ์ถํ ์ ์๋ค.
โฐ function* ํค์๋๋ก ๋ง๋ ํจ์๋ฅผ '์์ฑ๊ธฐ(generator)'๋ผ๊ณ ํ๋ค.
โฐ ์์ฑ๊ธฐ๋ ๋ฐ๋ณต๊ธฐ๋ฅผ ์ฝ๊ฒ ๋ง๋ค์ด ์ค๋ค(๋ฐ๋ณต๊ธฐ ์ ๊ณต์๋ก ๋์ํ๋ค)
export function* generator() {
console.log('generator started...')
let value = 1
while(value < 4)
yield value++
console.log('generator finished...')
}
for(let value of generator())
console.log(value)
// generator started...
// 1
// 2
// 3
// generator finished...
๐ setInterval ํจ์์ ์์ฑ๊ธฐ์ ์ ์ฌ์ฑ
โฐ ์์ฑ๊ธฐ๊ฐ ๋์ํ๋ ๋ฐฉ์ : ์ธ๋ฏธ์ฝ๋ฃจํด
โ ์ธ๋ฏธ์ฝ๋ฃจํด์ด๋?
โฐ ํ์ ์คํฌ๋ฆฝํธ์ฒ๋ผ ๋จ์ผ ์ค๋ ๋๋ก ๋์ํ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๊ฐ ๋ง์น ๋ค์ค ์ค๋ ๋๋ก ๋์ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ํ๋ ๊ธฐ๋ฅ
โฐ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณตํ๋ setInterval ํจ์๋ฅผ ์ฌ์ฉํด ์ธ๋ฏธ์ฝ๋ฃจํด ๋์ ๋ฐฉ์์ ๊ตฌํํ ์ ์๋ค.
const period = 1000
let count = 0
console.log('program started...')
const id = setInterval(() => {
if(count >= 3) {
clearInterval(id)
console.log('program finished...')
}
else
console.log(++count)
},period)
// program started...
// 1 1์ด ๊ฐ๊ฒฉ์ผ๋ก 1 2 3์ด ์ถ๋ ฅ๋๋ค.
// 2
// 3
// program finished
๐ function* ํค์๋
โฐ ์์ฑ๊ธฐ๋ ์ค์ง function* ํค์๋๋ก ์ ์ธํด์ผ ํ๋ฏ๋ก ํ์ดํ ํจ์๋ก๋ ์์ฑ๊ธฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
โฐ function* ์ ๊ทธ ์์ฒด๋ก ํค์๋์ด๊ณ , function ํค์๋์ *์ ๋ถ์ธ ๊ฒ์ด ์๋๋ค.
๐ yield ํค์๋
โฐ ๋ฐ๋ณต๊ธฐ๋ฅผ ์๋์ผ๋ก ๋ง๋ค์ด์ฃผ๋ฉฐ, ๋ฐ๋ณต๊ธฐ ์ ๊ณต์ ์ญํ ๋ ์ํํ๋ค.
// ์์ฑ๊ธฐ
export function* rangeGenerator(from: number, to: number) {
let value = from
while(value < to) {
yield value++
}
}
// while ํจํด์ผ๋ก ๋์ํ๋ ์์ฑ๊ธฐ
let iterator = rangeGenerator(1, 3+1)
while(1) {
const {value, done} = iterator.next()
if(done) break
console.log(value) // 1 2 3
}
// for...of ํจํด์ผ๋ก ๋์ํ๋ ์์ฑ๊ธฐ(ํด๋์ค๋ก ๋ง๋ค์ง ์์๋ of ๋ค์ ๋ค์ด๊ฐ ์ ์์
for(let value of rangeGenerator(4, 6+1))
console.log(value) // 5 6 7
๐ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์์ ๋ฉ์๋๋ก ๋์ํ๋ ์์ฑ๊ธฐ ๊ตฌํ
export class IterableUsingGenerator<T> implements Iterable<T> {
constructor(private values: T{] = [], private currentIndex: number = 0) {}
[Symbol.iterator] = function* () {
while(this.currentIndex < this.values.length)
yield this.values[this.currentIndex++]
}
}
โฐ ์์ฑ๊ธฐ๋ฅผ ํด๋์ค ๋ฉ์๋์ ๋ชธํต์ด ๋๊ฒ ํ๋ ค๋ฉด ๋ฐ๋์ [Symbol.iterator] = function* () ํ์์ผ๋ก ๊ตฌํํด์ผ ํ๋ค.
๐ yield* ํค์๋
โฐ yield๋ ๋จ์ํ ๊ฐ์ ๋์์ผ๋ก ๋์ํ์ง๋ง, yield*์ ๋ค๋ฅธ ์์ฑ๊ธฐ๋ ๋ฐฐ์ด์ ๋์์ผ๋ก ๋์ํ๋ค.
function* gen12(){
yield 1
yield 2
}
export function* gen12345() {
yield* gen12()
yield* [3, 4]
yield 5
}
import {gen12345} from './yield-star'
for(let value of gen12345())
console.log(value) // 1 2 3 4 5
โฐ gen12345() ํจ์๊ฐ ํธ์ถ๋๋ฉด, yield* gen12() ํจ์๊ฐ ํธ์ถ๋์ yield๋ฌธ์ด ๊ฐ 1์ ์์ฑํ๊ณ ์ฝ๋๋ ์ ์งํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค์ for๋ฌธ์ ์ํด yield* gen(12) ๊ฐ ์คํ๋๊ณ , ์ ์ง๊ฐ ํ๋ฆฌ๋ฉด์ ๊ฐ 2๋ฅผ ์์ฑํ๋ค.
๐ yield ๋ฐํ๊ฐ
export function* gen() {
let count = 5
let select = 0
while(count--) {
select = yield `you select ${select}`
}
}
export const random = (max, min=0) => Math.rount(Math.random() * (max-min)) + min
import {random, gen} from './yield-return'
const iter = gen()
while(true) {
const {value, done} = iter.next(random(10, 1))
if(done) break
console.log(value)
}
โฐ yield ์ฐ์ฐ์์ ๋ฐํ๊ฐ์ ๋ฐ๋ณต๊ธฐ์ next ๋ฉ์๋ ํธ์ถ ๋ ๋งค๊ฐ๋ณ์์ ์ ๋ฌํ๋ ๊ฐ์ด๋ค.
โฐ const {value, done} = iter.next(random(10, 1)) ๊ตฌ๋ฌธ์ next ๋ฉ์๋ ํธ์ถ ๋ ๋์๋ฅผ ์์ฑํด ์ ๋ฌํ๋ค.
'Study > TypeScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TS] ํจ์ ์กฐํฉ์ ์๋ฆฌ์ ์์ฉ (0) | 2023.02.09 |
---|---|
[TS] Promise์ async/await ๊ตฌ๋ฌธ (0) | 2023.02.06 |
[TS] ๋ฐฐ์ด๊ณผ ํํ (2) | 2023.02.02 |
[TS] ํจ์์ ๋ฉ์๋ (0) | 2023.02.01 |
[TS] ๊ฐ์ฒด์ ํ์ (2) | 2023.02.01 |