μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§μ κ°λ ₯ν λ°μ΄ν° μ²λ¦¬ λ₯λ ₯μ μμ보μΈμ. ν¨μ¨μ±κ³Ό μ±λ₯ ν₯μμ μν μ€νΈλ¦Ό μμ μ΅μ ν λ°©λ²μ λ°°μλλ€.
μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§: μ€νΈλ¦Ό μ²λ¦¬ μ±λ₯ ν₯μ
νλ μλ°μ€ν¬λ¦½νΈ κ°λ°μμ ν¨μ¨μ μΈ λ°μ΄ν° μ²λ¦¬λ λ§€μ° μ€μν©λλ€. λμ©λ λ°μ΄ν°μ , 볡μ‘ν λ³ν, λΉλκΈ° μμ μ μ²λ¦¬νλ €λ©΄ κ°λ ₯νκ³ μ΅μ νλ μ루μ μ΄ νμν©λλ€. μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§μ μ΄ν°λ μ΄ν°, μ λλ μ΄ν° ν¨μ, ν¨μν νλ‘κ·Έλλ° ν¨λ¬λ€μμ κΈ°λ₯μ νμ©νμ¬ μ€νΈλ¦Ό μ²λ¦¬μ λν κ°λ ₯νκ³ μ μ°ν μ κ·Ό λ°©μμ μ 곡ν©λλ€. μ΄ κΈμμλ μ΄ μμ§μ ν΅μ¬ κ°λ , μ΄μ , μ€μ μ μ© μ¬λ‘λ₯Ό μ΄ν΄λ³΄κ³ κ°λ°μκ° λ κΉλνκ³ μ±λ₯μ΄ λ°μ΄λλ©° μ μ§λ³΄μνκΈ° μ¬μ΄ μ½λλ₯Ό μμ±ν μ μλλ‘ λμ΅λλ€.
μ€νΈλ¦Όμ΄λ 무μμΈκ°?
μ€νΈλ¦Όμ μκ°μ νλ¦μ λ°λΌ μ¬μ© κ°λ₯ν΄μ§λ λ°μ΄ν° μμμ μνμ€μ λλ€. λͺ¨λ λ°μ΄ν°λ₯Ό ν λ²μ λ©λͺ¨λ¦¬μ 보κ΄νλ κΈ°μ‘΄ λ°°μ΄κ³Ό λ¬λ¦¬, μ€νΈλ¦Όμ λ°μ΄ν°κ° λμ°©νλ λλ‘ μ²ν¬ λλ κ°λ³ μμ λ¨μλ‘ μ²λ¦¬ν©λλ€. μ΄ μ κ·Ό λ°©μμ μ 체 λ°μ΄ν°μ μ ν λ²μ μ²λ¦¬νλ κ²μ΄ λΉμ€μ©μ μ΄κ±°λ λΆκ°λ₯ν λμ©λ λ°μ΄ν°μ μ΄λ μ€μκ° λ°μ΄ν° νΌλλ₯Ό λ€λ£° λ νΉν μ μ©ν©λλ€. μ€νΈλ¦Όμ μ ν(μ μλ λμ΄ μμ)νκ±°λ 무ν(μ§μμ μΌλ‘ λ°μ΄ν°λ₯Ό μμ±)ν μ μμ΅λλ€.
μλ°μ€ν¬λ¦½νΈμμ μ€νΈλ¦Όμ μ΄ν°λ μ΄ν°μ μ λλ μ΄ν° ν¨μλ₯Ό μ¬μ©νμ¬ ννν μ μμΌλ©°, μ΄λ₯Ό ν΅ν΄ μ§μ° νκ°(lazy evaluation)μ ν¨μ¨μ μΈ λ©λͺ¨λ¦¬ μ¬μ©μ΄ κ°λ₯ν©λλ€. μ΄ν°λ μ΄ν°λ μνμ€μ ν΄λΉ μνμ€μ λ€μ μμμ μ κ·Όνλ λ©μλλ₯Ό μ μνλ κ°μ²΄μ
λλ€. ES6μ λμ
λ μ λλ μ΄ν° ν¨μλ yield
ν€μλλ₯Ό μ¬μ©νμ¬ νμμ λ°λΌ κ°μ μμ±ν¨μΌλ‘μ¨ μ΄ν°λ μ΄ν°λ₯Ό νΈλ¦¬νκ² λ§λ€ μ μλ λ°©λ²μ μ 곡ν©λλ€.
μ΅μ νμ νμμ±
μ΄ν°λ μ΄ν°μ μ€νΈλ¦Όμ λ©λͺ¨λ¦¬ ν¨μ¨μ± λ° μ§μ° νκ° μΈ‘λ©΄μμ μλΉν μ΄μ μ μ 곡νμ§λ§, μμ§ν ꡬνμ μ¬μ ν μ±λ₯ λ³λͺ© νμμ μ΄λν μ μμ΅λλ€. μλ₯Ό λ€μ΄, λμ©λ λ°μ΄ν°μ μ λ°λ³΅μ μΌλ‘ μννκ±°λ κ° μμμ 볡μ‘ν λ³νμ μννλ κ²μ κ³μ° λΉμ©μ΄ λ§μ΄ λ€ μ μμ΅λλ€. λ°λ‘ μ΄ μ§μ μμ μ€νΈλ¦Ό μ΅μ νκ° νμν©λλ€.
μ€νΈλ¦Ό μ΅μ νλ λ€μκ³Ό κ°μ λ°©λ²μΌλ‘ μ€νΈλ¦Ό μ²λ¦¬μ κ΄λ ¨λ μ€λ²ν€λλ₯Ό μ΅μννλ κ²μ λͺ©νλ‘ ν©λλ€:
- λΆνμν λ°λ³΅ μ€μ΄κΈ°: μ°μ°μ μ§λ₯μ μΌλ‘ κ²°ν©νκ±°λ λ¨λ½(short-circuiting)νμ¬ μ€λ³΅ κ³μ°μ νΌν©λλ€.
- μ§μ° νκ° νμ©: κ²°κ³Όκ° μ€μ λ‘ νμν λκΉμ§ κ³μ°μ μ§μ°μμΌ, μ¬μ©λμ§ μμ μ μλ λ°μ΄ν°μ λΆνμν μ²λ¦¬λ₯Ό λ°©μ§ν©λλ€.
- λ°μ΄ν° λ³ν μ΅μ ν: νΉμ λ³νμ κ°μ₯ ν¨μ¨μ μΈ μκ³ λ¦¬μ¦κ³Ό λ°μ΄ν° ꡬ쑰λ₯Ό μ νν©λλ€.
- μμ λ³λ ¬ν: μ²λ¦¬ μμ μ μ¬λ¬ μ½μ΄λ μ€λ λμ λΆμ°νμ¬ μ²λ¦¬λμ ν₯μμν΅λλ€.
μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§ μκ°
μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§μ μ€νΈλ¦Ό μ²λ¦¬ μν¬νλ‘μ°λ₯Ό μ΅μ ννκΈ° μν μΌλ ¨μ λꡬμ κΈ°μ μ μ 곡ν©λλ€. μ΄λ μΌλ°μ μΌλ‘ μ΄ν°λ μ΄ν°μ μ λλ μ΄ν°μ λν΄ μλνλ ν¬νΌ ν¨μ λͺ¨μμΌλ‘ ꡬμ±λμ΄ μμΌλ©°, κ°λ°μκ° μ μΈμ μ΄κ³ ν¨μ¨μ μΈ λ°©μμΌλ‘ μμ μ μ°κ²°ν μ μλλ‘ ν©λλ€. μ΄λ¬ν ν¬νΌ ν¨μλ μ’ μ’ μ§μ° νκ°, λ¨λ½ νκ°, λ°μ΄ν° μΊμ±κ³Ό κ°μ μ΅μ ν κΈ°λ²μ ν΅ν©νμ¬ μ²λ¦¬ μ€λ²ν€λλ₯Ό μ΅μνν©λλ€.
μμ§μ ν΅μ¬ κ΅¬μ± μμλ μΌλ°μ μΌλ‘ λ€μκ³Ό κ°μ΅λλ€:
- μ΄ν°λ μ΄ν° ν¬νΌ: λ§€ν, νν°λ§, 리λμ± λ° λ°μ΄ν° λ³νκ³Ό κ°μ μΌλ°μ μΈ μ€νΈλ¦Ό μμ μ μννλ ν¨μμ λλ€.
- μ΅μ ν μ λ΅: μ§μ° νκ°, λ¨λ½ νκ°, λ³λ ¬νμ κ°μ΄ μ€νΈλ¦Ό μμ μ μ±λ₯μ ν₯μμν€λ κΈ°μ μ λλ€.
- μ€νΈλ¦Ό μΆμν: μ΄ν°λ μ΄ν°μ μ λλ μ΄ν°μ 볡μ‘μ±μ μ¨κΈ°κ³ μ€νΈλ¦Όμ μμ± λ° μ‘°μμ λ¨μννλ μμ μμ€μ μΆμνμ λλ€.
μ£Όμ μ΄ν°λ μ΄ν° ν¬νΌ ν¨μ
λ€μμ κ°μ₯ μΌλ°μ μΌλ‘ μ¬μ©λλ μ΄ν°λ μ΄ν° ν¬νΌ ν¨μ μ€ μΌλΆμ λλ€:
map
map
ν¨μλ μ£Όμ΄μ§ ν¨μλ₯Ό μ€νΈλ¦Όμ κ° μμμ μ μ©νμ¬ λ³νν©λλ€. λ³νλ μμλ€μ ν¬ν¨νλ μλ‘μ΄ μ€νΈλ¦Όμ λ°νν©λλ€.
μμ : μ«μ μ€νΈλ¦Όμ μ κ³± κ°μΌλ‘ λ³ννκΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
}
function map(iterator, transform) {
return {
next() {
const { value, done } = iterator.next();
if (done) {
return { value: undefined, done: true };
}
return { value: transform(value), done: false };
},
[Symbol.iterator]() {
return this;
},
};
}
const squaredNumbers = map(numbers(), (x) => x * x);
for (const num of squaredNumbers) {
console.log(num); // Output: 1, 4, 9
}
filter
filter
ν¨μλ μ£Όμ΄μ§ 쑰건μ λ§μ‘±νλ μ€νΈλ¦Όμ μμλ€μ μ νν©λλ€. νν°λ₯Ό ν΅κ³Όν μμλ€λ§ ν¬ν¨νλ μλ‘μ΄ μ€νΈλ¦Όμ λ°νν©λλ€.
μμ : μ€νΈλ¦Όμμ μ§μ νν°λ§νκΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
function filter(iterator, predicate) {
return {
next() {
while (true) {
const { value, done } = iterator.next();
if (done) {
return { value: undefined, done: true };
}
if (predicate(value)) {
return { value, done: false };
}
}
},
[Symbol.iterator]() {
return this;
},
};
}
const evenNumbers = filter(numbers(), (x) => x % 2 === 0);
for (const num of evenNumbers) {
console.log(num); // Output: 2, 4
}
reduce
reduce
ν¨μλ 리λμ ν¨μλ₯Ό κ° μμμ λμ κΈ°μ μ μ©νμ¬ μ€νΈλ¦Όμ μμλ€μ λ¨μΌ κ°μΌλ‘ μ§κ³ν©λλ€. μ΅μ’
λμ λ κ°μ λ°νν©λλ€.
μμ : μ€νΈλ¦Όμ μλ μ«μλ€μ ν© κ΅¬νκΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
function reduce(iterator, reducer, initialValue) {
let accumulator = initialValue;
let next = iterator.next();
while (!next.done) {
accumulator = reducer(accumulator, next.value);
next = iterator.next();
}
return accumulator;
}
const sum = reduce(numbers(), (acc, x) => acc + x, 0);
console.log(sum); // Output: 15
find
find
ν¨μλ μ£Όμ΄μ§ 쑰건μ λ§μ‘±νλ μ€νΈλ¦Όμ 첫 λ²μ§Έ μμλ₯Ό λ°νν©λλ€. μΌμΉνλ μμλ₯Ό μ°ΎμΌλ©΄ μ¦μ λ°λ³΅μ μ€λ¨ν©λλ€.
μμ : μ€νΈλ¦Όμμ 첫 λ²μ§Έ μ§μ μ°ΎκΈ°.
function* numbers() {
yield 1;
yield 3;
yield 2;
yield 4;
yield 5;
}
function find(iterator, predicate) {
let next = iterator.next();
while (!next.done) {
if (predicate(next.value)) {
return next.value;
}
next = iterator.next();
}
return undefined;
}
const firstEvenNumber = find(numbers(), (x) => x % 2 === 0);
console.log(firstEvenNumber); // Output: 2
forEach
forEach
ν¨μλ μ€νΈλ¦Όμ κ° μμμ λν΄ μ 곡λ ν¨μλ₯Ό ν λ²μ© μ€νν©λλ€. μλ‘μ΄ μ€νΈλ¦Όμ λ°ννκ±°λ μλ³Έ μ€νΈλ¦Όμ μμ νμ§ μμ΅λλ€.
μμ : μ€νΈλ¦Όμ κ° μ«μ μΆλ ₯νκΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
}
function forEach(iterator, action) {
let next = iterator.next();
while (!next.done) {
action(next.value);
next = iterator.next();
}
}
forEach(numbers(), (x) => console.log(x)); // Output: 1, 2, 3
some
some
ν¨μλ μ€νΈλ¦Όμ μμ μ€ νλλΌλ μ£Όμ΄μ§ 쑰건μ λ§μ‘±νλμ§ ν
μ€νΈν©λλ€. μ΄λ€ μμλΌλ 쑰건μ λ§μ‘±νλ©΄ true
λ₯Ό λ°ννκ³ , κ·Έλ μ§ μμΌλ©΄ false
λ₯Ό λ°νν©λλ€. μΌμΉνλ μμλ₯Ό μ°ΎμΌλ©΄ μ¦μ λ°λ³΅μ μ€λ¨ν©λλ€.
μμ : μ€νΈλ¦Όμ μ§μκ° ν¬ν¨λμ΄ μλμ§ νμΈνκΈ°.
function* numbers() {
yield 1;
yield 3;
yield 5;
yield 2;
yield 7;
}
function some(iterator, predicate) {
let next = iterator.next();
while (!next.done) {
if (predicate(next.value)) {
return true;
}
next = iterator.next();
}
return false;
}
const hasEvenNumber = some(numbers(), (x) => x % 2 === 0);
console.log(hasEvenNumber); // Output: true
every
every
ν¨μλ μ€νΈλ¦Όμ λͺ¨λ μμκ° μ£Όμ΄μ§ 쑰건μ λ§μ‘±νλμ§ ν
μ€νΈν©λλ€. λͺ¨λ μμκ° μ‘°κ±΄μ λ§μ‘±νλ©΄ true
λ₯Ό λ°ννκ³ , κ·Έλ μ§ μμΌλ©΄ false
λ₯Ό λ°νν©λλ€. 쑰건μ λ§μ‘±νμ§ μλ μμλ₯Ό μ°ΎμΌλ©΄ μ¦μ λ°λ³΅μ μ€λ¨ν©λλ€.
μμ : μ€νΈλ¦Όμ λͺ¨λ μ«μκ° μμμΈμ§ νμΈνκΈ°.
function* numbers() {
yield 1;
yield 3;
yield 5;
yield 7;
yield 9;
}
function every(iterator, predicate) {
let next = iterator.next();
while (!next.done) {
if (!predicate(next.value)) {
return false;
}
next = iterator.next();
}
return true;
}
const allPositive = every(numbers(), (x) => x > 0);
console.log(allPositive); // Output: true
flatMap
flatMap
ν¨μλ μ€νΈλ¦Όμ κ° μμλ₯Ό μ£Όμ΄μ§ ν¨μλ₯Ό μ μ©νμ¬ λ³νν λ€μ, κ²°κ³Όλ‘ λμ¨ μ€νΈλ¦Όλ€μ μ€νΈλ¦Όμ λ¨μΌ μ€νΈλ¦ΌμΌλ‘ νννν©λλ€. map
μ νΈμΆν ν flat
μ νΈμΆνλ κ²κ³Ό λμΌν©λλ€.
μμ : λ¬Έμ₯ μ€νΈλ¦Όμ λ¨μ΄ μ€νΈλ¦ΌμΌλ‘ λ³ννκΈ°.
function* sentences() {
yield "This is a sentence.";
yield "Another sentence here.";
}
function* words(sentence) {
const wordList = sentence.split(' ');
for (const word of wordList) {
yield word;
}
}
function flatMap(iterator, transform) {
return {
next() {
if (!this.currentIterator) {
const { value, done } = iterator.next();
if (done) {
return { value: undefined, done: true };
}
this.currentIterator = transform(value)[Symbol.iterator]();
}
const nextValue = this.currentIterator.next();
if (nextValue.done) {
this.currentIterator = undefined;
return this.next(); // Recursively call next to get the next value from the outer iterator
}
return nextValue;
},
[Symbol.iterator]() {
return this;
},
};
}
const allWords = flatMap(sentences(), words);
for (const word of allWords) {
console.log(word); // Output: This, is, a, sentence., Another, sentence, here.
}
take
take
ν¨μλ μλ³Έ μ€νΈλ¦Όμμ μ²μ n
κ°μ μμλ₯Ό ν¬ν¨νλ μλ‘μ΄ μ€νΈλ¦Όμ λ°νν©λλ€.
μμ : μ€νΈλ¦Όμμ μ²μ 3κ°μ μ«μ κ°μ Έμ€κΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
function take(iterator, n) {
let count = 0;
return {
next() {
if (count >= n) {
return { value: undefined, done: true };
}
const { value, done } = iterator.next();
if (done) {
return { value: undefined, done: true };
}
count++;
return { value, done: false };
},
[Symbol.iterator]() {
return this;
},
};
}
const firstThree = take(numbers(), 3);
for (const num of firstThree) {
console.log(num); // Output: 1, 2, 3
}
drop
drop
ν¨μλ μλ³Έ μ€νΈλ¦Όμμ μ²μ n
κ°μ μμλ₯Ό μ μΈν λͺ¨λ μμλ₯Ό ν¬ν¨νλ μλ‘μ΄ μ€νΈλ¦Όμ λ°νν©λλ€.
μμ : μ€νΈλ¦Όμμ μ²μ 2κ°μ μ«μ μ μΈνκΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
function drop(iterator, n) {
let count = 0;
while (count < n) {
const { done } = iterator.next();
if (done) {
return {
next() { return { value: undefined, done: true }; },
[Symbol.iterator]() { return this; }
};
}
count++;
}
return iterator;
}
const afterTwo = drop(numbers(), 2);
for (const num of afterTwo) {
console.log(num); // Output: 3, 4, 5
}
toArray
toArray
ν¨μλ μ€νΈλ¦Όμ μλΉνκ³ μ€νΈλ¦Όμ λͺ¨λ μμλ₯Ό ν¬ν¨νλ λ°°μ΄μ λ°νν©λλ€.
μμ : μ«μ μ€νΈλ¦Όμ λ°°μ΄λ‘ λ³ννκΈ°.
function* numbers() {
yield 1;
yield 2;
yield 3;
}
function toArray(iterator) {
const result = [];
let next = iterator.next();
while (!next.done) {
result.push(next.value);
next = iterator.next();
}
return result;
}
const numberArray = toArray(numbers());
console.log(numberArray); // Output: [1, 2, 3]
μ΅μ ν μ λ΅
μ§μ° νκ° (Lazy Evaluation)
μ§μ° νκ°λ κ³μ° κ²°κ³Όκ° μ€μ λ‘ νμν λκΉμ§ μ€νμ 미루λ κΈ°μ μ
λλ€. μ΄λ μ¬μ©λμ§ μμ μ μλ λ°μ΄ν°μ λν λΆνμν μ²λ¦¬λ₯Ό νΌν¨μΌλ‘μ¨ μ±λ₯μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€. μ΄ν°λ μ΄ν° ν¬νΌ ν¨μλ νμμ λ°λΌ κ°μ μμ±νλ μ΄ν°λ μ΄ν°μ λν΄ μλνκΈ° λλ¬Έμ λ³Έμ§μ μΌλ‘ μ§μ° νκ°λ₯Ό μ§μν©λλ€. μ¬λ¬ μ΄ν°λ μ΄ν° ν¬νΌ ν¨μλ₯Ό ν¨κ» μ°κ²°νλ©΄, κ³μ°μ κ²°κ³Ό μ€νΈλ¦Όμ΄ μλΉλ λ(μ: for...of
루νλ‘ μννκ±°λ toArray
λ‘ λ°°μ΄λ‘ λ³νν λ)λ§ μνλ©λλ€.
μμ :
function* largeDataSet() {
for (let i = 0; i < 1000000; i++) {
yield i;
}
}
const processedData = map(filter(largeDataSet(), (x) => x % 2 === 0), (x) => x * 2);
// No computations are performed until we iterate over processedData
let count = 0;
for (const num of processedData) {
console.log(num);
count++;
if (count > 10) {
break; // Only process the first 10 elements
}
}
μ΄ μμ μμ largeDataSet
μ λλ μ΄ν°λ λ°±λ§ κ°μ μ«μλ₯Ό μμ±ν©λλ€. κ·Έλ¬λ map
κ³Ό filter
μ°μ°μ for...of
루νκ° processedData
μ€νΈλ¦Όμ μνν λκΉμ§ μνλμ§ μμ΅λλ€. 루νλ μ²μ 10κ°μ μμλ§ μ²λ¦¬νλ―λ‘, μ²μ 10κ°μ μ§μλ§ λ³νλκ³ λλ¨Έμ§ μμμ λν λΆνμν κ³μ°μ νΌνκ² λ©λλ€.
λ¨λ½ νκ° (Short-Circuiting)
λ¨λ½ νκ°λ κ²°κ³Όκ° μλ €μ§λ μ¦μ κ³μ° μ€νμ μ€λ¨νλ κΈ°μ μ
λλ€. μ΄λ find
, some
, every
μ κ°μ μμ
μ νΉν μ μ©ν μ μμΌλ©°, μΌμΉνλ μμλ₯Ό μ°Ύκ±°λ μ‘°κ±΄μ΄ μλ°λλ©΄ λ°λ³΅μ μ‘°κΈ°μ μ’
λ£ν μ μμ΅λλ€.
μμ :
function* infiniteNumbers() {
let i = 0;
while (true) {
yield i++;
}
}
const hasValueGreaterThan1000 = some(infiniteNumbers(), (x) => x > 1000);
console.log(hasValueGreaterThan1000); // Output: true
μ΄ μμ μμ infiniteNumbers
μ λλ μ΄ν°λ 무νν μ«μ μ€νΈλ¦Όμ μμ±ν©λλ€. κ·Έλ¬λ some
ν¨μλ 1000λ³΄λ€ ν° μ«μλ₯Ό μ°Ύλ μ¦μ λ°λ³΅μ μ€λ¨νμ¬ λ¬΄ν 루νλ₯Ό νΌν©λλ€.
λ°μ΄ν° μΊμ± (Data Caching)
λ°μ΄ν° μΊμ±μ κ³μ° κ²°κ³Όλ₯Ό μ μ₯νμ¬ λμ€μ λ€μ κ³μ°ν νμ μμ΄ μ¬μ¬μ©ν μ μλλ‘ νλ κΈ°μ μ λλ€. μ΄λ μ¬λ¬ λ² μλΉλλ μ€νΈλ¦Όμ΄λ κ³μ° λΉμ©μ΄ λ§μ΄ λλ μμλ₯Ό ν¬ν¨νλ μ€νΈλ¦Όμ μ μ©ν μ μμ΅λλ€.
μμ :
function* expensiveComputations() {
for (let i = 0; i < 5; i++) {
console.log("Calculating value for", i); // This will only print once for each value
yield i * i * i;
}
}
function cachedStream(iterator) {
const cache = [];
let index = 0;
return {
next() {
if (index < cache.length) {
return { value: cache[index++], done: false };
}
const next = iterator.next();
if (next.done) {
return next;
}
cache.push(next.value);
index++;
return next;
},
[Symbol.iterator]() {
return this;
},
};
}
const cachedData = cachedStream(expensiveComputations());
// First iteration
for (const num of cachedData) {
console.log("First iteration:", num);
}
// Second iteration - values are retrieved from the cache
for (const num of cachedData) {
console.log("Second iteration:", num);
}
μ΄ μμ μμ expensiveComputations
μ λλ μ΄ν°λ κ° μμμ λν΄ κ³μ° λΉμ©μ΄ λ§μ΄ λλ μμ
μ μνν©λλ€. cachedStream
ν¨μλ μ΄λ¬ν κ³μ° κ²°κ³Όλ₯Ό μΊμνμ¬ ν λ²λ§ μνλλλ‘ ν©λλ€. cachedData
μ€νΈλ¦Όμ λν λ λ²μ§Έ λ°λ³΅μ μΊμμμ κ°μ κ²μνμ¬ μ€λ³΅ κ³μ°μ νΌν©λλ€.
μ€μ©μ μΈ μ μ© μ¬λ‘
μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§μ λ€μκ³Ό κ°μ κ΄λ²μν μ€μ μμ© λΆμΌμ μ μ©λ μ μμ΅λλ€:
- λ°μ΄ν° μ²λ¦¬ νμ΄νλΌμΈ: λ€μν μμ€λ‘λΆν° λ°μ΄ν°λ₯Ό λ³ν, νν°λ§ λ° μ§κ³νλ 볡μ‘ν λ°μ΄ν° μ²λ¦¬ νμ΄νλΌμΈ ꡬμΆ.
- μ€μκ° λ°μ΄ν° μ€νΈλ¦Ό: μΌμ, μμ λ―Έλμ΄ νΌλ λλ κΈμ΅ μμ₯μ μ€μκ° λ°μ΄ν° μ€νΈλ¦Ό μ²λ¦¬.
- λΉλκΈ° μμ : API νΈμΆμ΄λ λ°μ΄ν°λ² μ΄μ€ 쿼리μ κ°μ λΉλκΈ° μμ μ λ ΌλΈλ‘νΉ λ° ν¨μ¨μ μΈ λ°©μμΌλ‘ μ²λ¦¬.
- λμ©λ νμΌ μ²λ¦¬: λμ©λ νμΌμ μ²ν¬ λ¨μλ‘ μ²λ¦¬νμ¬ λ©λͺ¨λ¦¬ λ¬Έμ λ₯Ό νΌνκ³ μ±λ₯ ν₯μ.
- μ¬μ©μ μΈν°νμ΄μ€ μ λ°μ΄νΈ: λ°μ΄ν° λ³κ²½μ λ°λΌ λ°μμ μ΄κ³ ν¨μ¨μ μΈ λ°©μμΌλ‘ μ¬μ©μ μΈν°νμ΄μ€ μ λ°μ΄νΈ.
μμ : λ°μ΄ν° μ²λ¦¬ νμ΄νλΌμΈ ꡬμΆ
κ³ κ° λ°μ΄ν°κ° ν¬ν¨λ λμ©λ CSV νμΌμ μ²λ¦¬ν΄μΌ νλ μλ리μ€λ₯Ό μκ°ν΄ λ΄ μλ€. νμ΄νλΌμΈμ λ€μμ μνν΄μΌ ν©λλ€:
- CSV νμΌμ μ²ν¬ λ¨μλ‘ μ½μ΅λλ€.
- κ° μ²ν¬λ₯Ό κ°μ²΄ λ°°μ΄λ‘ νμ±ν©λλ€.
- 18μΈ λ―Έλ§μΈ κ³ κ°μ νν°λ§ν©λλ€.
- λ¨μ κ³ κ°μ λ¨μνλ λ°μ΄ν° κ΅¬μ‘°λ‘ λ§€νν©λλ€.
- λ¨μ κ³ κ°μ νκ· μ°λ Ήμ κ³μ°ν©λλ€.
async function* readCsvFile(filePath, chunkSize) {
const fileHandle = await fs.open(filePath, 'r');
const stream = fileHandle.readableWebStream();
const reader = stream.getReader();
let decoder = new TextDecoder('utf-8');
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
yield decoder.decode(value);
}
} finally {
fileHandle.close();
}
}
function* parseCsvChunk(csvChunk) {
const lines = csvChunk.split('\n');
const headers = lines[0].split(',');
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
if (values.length !== headers.length) continue; // Skip incomplete lines
const customer = {};
for (let j = 0; j < headers.length; j++) {
customer[headers[j]] = values[j];
}
yield customer;
}
}
async function processCustomerData(filePath) {
const customerStream = flatMap(readCsvFile(filePath, 1024 * 1024), parseCsvChunk);
const validCustomers = filter(customerStream, (customer) => parseInt(customer.age) >= 18);
const simplifiedCustomers = map(validCustomers, (customer) => ({
name: customer.name,
age: parseInt(customer.age),
city: customer.city,
}));
let sum = 0;
let count = 0;
for await (const customer of simplifiedCustomers) {
sum += customer.age;
count++;
}
const averageAge = count > 0 ? sum / count : 0;
console.log("Average age of adult customers:", averageAge);
}
// Example usage:
// Assuming you have a file named 'customers.csv'
// processCustomerData('customers.csv');
μ΄ μμ λ μ΄ν°λ μ΄ν° ν¬νΌλ₯Ό μ¬μ©νμ¬ λ°μ΄ν° μ²λ¦¬ νμ΄νλΌμΈμ ꡬμΆνλ λ°©λ²μ 보μ¬μ€λλ€. readCsvFile
ν¨μλ CSV νμΌμ μ²ν¬ λ¨μλ‘ μ½κ³ , parseCsvChunk
ν¨μλ κ° μ²ν¬λ₯Ό κ³ κ° κ°μ²΄ λ°°μ΄λ‘ νμ±νλ©°, filter
ν¨μλ 18μΈ λ―Έλ§ κ³ κ°μ νν°λ§νκ³ , map
ν¨μλ λλ¨Έμ§ κ³ κ°μ λ¨μνλ λ°μ΄ν° κ΅¬μ‘°λ‘ λ§€ννλ©°, λ§μ§λ§ 루νλ λλ¨Έμ§ κ³ κ°μ νκ· μ°λ Ήμ κ³μ°ν©λλ€. μ΄ν°λ μ΄ν° ν¬νΌμ μ§μ° νκ°λ₯Ό νμ©ν¨μΌλ‘μ¨, μ΄ νμ΄νλΌμΈμ μ 체 νμΌμ λ©λͺ¨λ¦¬μ λ‘λνμ§ μκ³ λ λμ©λ CSV νμΌμ ν¨μ¨μ μΌλ‘ μ²λ¦¬ν μ μμ΅λλ€.
λΉλκΈ° μ΄ν°λ μ΄ν° (Async Iterators)
νλ μλ°μ€ν¬λ¦½νΈλ λΉλκΈ° μ΄ν°λ μ΄ν°λ λμ νμ΅λλ€. λΉλκΈ° μ΄ν°λ μ΄ν°μ μ λλ μ΄ν°λ λκΈ°μ λμλ¬Όκ³Ό μ μ¬νμ§λ§, λ°λ³΅ νλ‘μΈμ€ λ΄μμ λΉλκΈ° μμ μ νμ©ν©λλ€. μ΄λ API νΈμΆμ΄λ λ°μ΄ν°λ² μ΄μ€ 쿼리μ κ°μ λΉλκΈ° λ°μ΄ν° μμ€λ₯Ό λ€λ£° λ νΉν μ μ©ν©λλ€.
λΉλκΈ° μ΄ν°λ μ΄ν°λ₯Ό λ§λ€λ €λ©΄ async function*
ꡬ문μ μ¬μ©ν μ μμ΅λλ€. yield
ν€μλλ₯Ό μ¬μ©νμ¬ νλ‘λ―Έμ€λ₯Ό μμ±ν μ μμΌλ©°, μ΄ νλ‘λ―Έμ€λ μ΄ν°λ μ΄ν°μ μν΄ λ°νλκΈ° μ μ μλμΌλ‘ ν΄κ²°λ©λλ€.
μμ :
async function* fetchUsers() {
for (let i = 1; i <= 3; i++) {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${i}`);
const user = await response.json();
yield user;
}
}
async function main() {
for await (const user of fetchUsers()) {
console.log(user);
}
}
// main();
μ΄ μμ μμ fetchUsers
ν¨μλ μ격 APIμμ μ¬μ©μ λ°μ΄ν°λ₯Ό κ°μ Έμ΅λλ€. yield
ν€μλλ νλ‘λ―Έμ€λ₯Ό μμ±νλ λ° μ¬μ©λλ©°, μ΄ νλ‘λ―Έμ€λ μ΄ν°λ μ΄ν°μ μν΄ λ°νλκΈ° μ μ μλμΌλ‘ ν΄κ²°λ©λλ€. for await...of
루νλ λΉλκΈ° μ΄ν°λ μ΄ν°λ₯Ό μννλ λ° μ¬μ©λλ©°, κ° νλ‘λ―Έμ€κ° ν΄κ²°λ λκΉμ§ κΈ°λ€λ¦° ν μ¬μ©μ λ°μ΄ν°λ₯Ό μ²λ¦¬ν©λλ€.
λΉλκΈ° μ΄ν°λ μ΄ν° ν¬νΌλ μ€νΈλ¦Όμμ λΉλκΈ° μμ
μ μ²λ¦¬νκΈ° μν΄ μ μ¬νκ² κ΅¬νλ μ μμ΅λλ€. μλ₯Ό λ€μ΄, μ€νΈλ¦Όμ κ° μμμ λΉλκΈ° λ³νμ μ μ©νκΈ° μν΄ asyncMap
ν¨μλ₯Ό λ§λ€ μ μμ΅λλ€.
κ²°λ‘
μλ°μ€ν¬λ¦½νΈ μ΄ν°λ μ΄ν° ν¬νΌ μ€νΈλ¦Ό μ΅μ ν μμ§μ μ€νΈλ¦Ό μ²λ¦¬μ λν κ°λ ₯νκ³ μ μ°ν μ κ·Ό λ°©μμ μ 곡νμ¬, κ°λ°μκ° λ κΉλνκ³ μ±λ₯μ΄ λ°μ΄λλ©° μ μ§λ³΄μνκΈ° μ¬μ΄ μ½λλ₯Ό μμ±ν μ μλλ‘ ν©λλ€. μ΄ν°λ μ΄ν°, μ λλ μ΄ν° ν¨μ, ν¨μν νλ‘κ·Έλλ° ν¨λ¬λ€μμ κΈ°λ₯μ νμ©ν¨μΌλ‘μ¨, μ΄ μμ§μ λ°μ΄ν° μ²λ¦¬ μν¬νλ‘μ°μ ν¨μ¨μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€. μ΄ μμ§μ ν΅μ¬ κ°λ , μ΅μ ν μ λ΅, μ€μ μ μ© μ¬λ‘λ₯Ό μ΄ν΄ν¨μΌλ‘μ¨ κ°λ°μλ λμ©λ λ°μ΄ν°μ , μ€μκ° λ°μ΄ν° μ€νΈλ¦Ό, λΉλκΈ° μμ μ μ²λ¦¬νκΈ° μν κ°λ ₯νκ³ νμ₯ κ°λ₯ν μ루μ μ ꡬμΆν μ μμ΅λλ€. μ΄λ¬ν ν¨λ¬λ€μ μ νμ λ°μλ€μ¬ μλ°μ€ν¬λ¦½νΈ κ°λ° κ΄νμ ν₯μμν€κ³ νλ‘μ νΈμμ μλ‘μ΄ μ°¨μμ ν¨μ¨μ±μ μ€ννμμμ€.