์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ์ต์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํจ์จ์ ์ด๊ณ ์ฐ์ํ ์คํธ๋ฆผ ๋ณํ์ ๊ตฌํํ์ธ์. ์ค์ฉ์ ์ธ ์์ ์ ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ์ ํตํด ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ๋ง์คํฐํ์ธ์.
์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ: ์ต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์คํธ๋ฆผ ๋ณํ
๋น ๋ฅด๊ฒ ๋ฐ์ ํ๋ ์ต์ ์น ๋ฐ ์๋ฒ์ฌ์ด๋ ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ๊ฐ๋ ฅํ ์กฐํฉ๊ธฐ์ ๊ฒฐํฉํ์ฌ ์ด๋ฌํ ์คํธ๋ฆผ์ ๋ณํํ๊ณ ์กฐ์ํ๊ธฐ ์ํ ์ฐ์ํ๊ณ ์ฑ๋ฅ ์ข์ ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ์ ๊ฐ๋ ์ ํ๊ตฌํ๊ณ , ๊ทธ ์ด์ ๊ณผ ์ค์ ์ ์ฉ ์ฌ๋ก, ๊ทธ๋ฆฌ๊ณ ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ฅผ ์ํ ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ์ ์๊ฐํฉ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ ์ดํดํ๊ธฐ
์กฐํฉ๊ธฐ์ ๋ํด ์์๋ณด๊ธฐ ์ ์ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ(Async Iterators)์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ(Async Generators)์ ๋ํ ํ์คํ ์ดํด๊ฐ ํ์ํฉ๋๋ค. ECMAScript 2018์ ๋์ ๋ ์ด ๊ธฐ๋ฅ๋ค์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์ํ์ค๋ฅผ ๊ตฌ์กฐํ๋๊ณ ์์ธก ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ๋ค๋ฃฐ ์ ์๊ฒ ํด์ค๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ next() ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ ๊ฐ์ฒด์
๋๋ค. ์ด ๋ฉ์๋๋ value์ done์ด๋ผ๋ ๋ ๊ฐ์ง ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ก ํด์๋๋ ํ๋ก๋ฏธ์ค(promise)๋ฅผ ๋ฐํํฉ๋๋ค. value ์์ฑ์ ์ํ์ค์ ๋ค์ ๊ฐ์, done ์์ฑ์ ์ดํฐ๋ ์ดํฐ๊ฐ ์ํ์ค์ ๋์ ๋๋ฌํ๋์ง๋ฅผ ๋ํ๋
๋๋ค.
๊ฐ๋จํ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
const asyncIterable = {
[Symbol.asyncIterator]() {
let i = 0;
return {
async next() {
await new Promise(resolve => setTimeout(resolve, 100)); // Simulate asynchronous operation
if (i < 3) {
return { value: i++, done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
};
(async () => {
for await (const value of asyncIterable) {
console.log(value); // Output: 0, 1, 2
}
})();
๋น๋๊ธฐ ์ ๋๋ ์ดํฐ
๋น๋๊ธฐ ์ ๋๋ ์ดํฐ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์์ฑํ๊ธฐ ์ํ ๋ ๊ฐ๊ฒฐํ ๊ตฌ๋ฌธ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ค์ async function* ๊ตฌ๋ฌธ์ผ๋ก ์ ์ธ๋ ํจ์์ด๋ฉฐ, yield ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์ ์์ฑํฉ๋๋ค.
๋น๋๊ธฐ ์ ๋๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ ๋์ผํ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
async function* asyncGenerator() {
let i = 0;
while (i < 3) {
await new Promise(resolve => setTimeout(resolve, 100));
yield i++;
}
}
(async () => {
for await (const value of asyncGenerator()) {
console.log(value); // Output: 0, 1, 2
}
})();
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ๋ ์๋ฐ์คํฌ๋ฆฝํธ์์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ค๋ฃจ๋ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ์์์ ๋๋ค. ์ด๋ฅผ ํตํด ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋ฐ์ดํฐ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํด์ง๋ ๋๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ ์๊ฐ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๋ ํ๋ ์ด์์ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ ์ ๋ ฅ ์คํธ๋ฆผ์ ์ด๋ค ๋ฐฉ์์ผ๋ก๋ ๋ณํํ๊ฑฐ๋ ๊ฒฐํฉํ๋ ์๋ก์ด ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ๋ ํจ์์ ๋๋ค. ์ด๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ ์์ ์๊ฐ์ ๋ฐ์์ผ๋ฉฐ, ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๊ฐ๋ ฅํ๊ณ ์กฐํฉ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์๋ ์ผ๋ถ ํจ์ํ ์ธ์ด์ฒ๋ผ ๋ด์ฅ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๊ฐ ์์ง๋ง, ์ง์ ์ฝ๊ฒ ๊ตฌํํ๊ฑฐ๋ ๊ธฐ์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ด๊ณ ์ ์ฉํ ๋ช ๊ฐ์ง ์กฐํฉ๊ธฐ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. map
map ์กฐํฉ๊ธฐ๋ ์ฃผ์ด์ง ํจ์๋ฅผ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๊ฐ ๋ฐฉ์ถํ๋ ๊ฐ ๊ฐ์ ์ ์ฉํ๊ณ , ๋ณํ๋ ๊ฐ์ ๋ฐฉ์ถํ๋ ์๋ก์ด ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ ๋ฐฐ์ด์ map ํจ์์ ์ ์ฌํฉ๋๋ค.
async function* map(iterable, fn) {
for await (const value of iterable) {
yield await fn(value);
}
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
async function square(x) {
await new Promise(resolve => setTimeout(resolve, 50)); // Simulate async operation
return x * x;
}
(async () => {
const squaredNumbers = map(numberGenerator(), square);
for await (const value of squaredNumbers) {
console.log(value); // Output: 1, 4, 9 (with delays)
}
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: map ์กฐํฉ๊ธฐ๋ ๋ค์ํ ์ง์ญ๊ณผ ์ฐ์
์ ๊ฑธ์ณ ๋๋ฆฌ ์ ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ๋ณํ์ ์ ์ฉํ ๋ ํ์งํ ๋ฐ ๊ตญ์ ํ ์๊ตฌ์ฌํญ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ ์ง๋ ์ซ์๋ฅผ ํฌํจํ๋ ๋ฐ์ดํฐ๋ฅผ ๋งคํํ๋ ๊ฒฝ์ฐ ๋ณํ ํจ์๊ฐ ๋ค์ํ ์ง์ญ๋ณ ํ์์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋๋ก ํด์ผ ํฉ๋๋ค.
2. filter
filter ์กฐํฉ๊ธฐ๋ ์ฃผ์ด์ง ์ ์ด ํจ์๋ฅผ ๋ง์กฑํ๋ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๊ฐ๋ง ๋ฐฉ์ถํฉ๋๋ค.
async function* filter(iterable, predicate) {
for await (const value of iterable) {
if (await predicate(value)) {
yield value;
}
}
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
async function isEven(x) {
await new Promise(resolve => setTimeout(resolve, 50));
return x % 2 === 0;
}
(async () => {
const evenNumbers = filter(numberGenerator(), isEven);
for await (const value of evenNumbers) {
console.log(value); // Output: 2, 4 (with delays)
}
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: filter์ ์ฌ์ฉ๋๋ ์ ์ด ํจ์๋ ๋ฌธํ์ ๋๋ ์ง์ญ์ ๋ฐ์ดํฐ ์ฐจ์ด๋ฅผ ๊ณ ๋ คํด์ผ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฐ๋ น์ ๋ฐ๋ผ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ํํฐ๋งํ๋ ๊ฒฝ์ฐ ๊ตญ๊ฐ๋ง๋ค ๋ค๋ฅธ ๊ธฐ์ค์ด๋ ๋ฒ์ ๊ณ ๋ ค์ฌํญ์ด ํ์ํ ์ ์์ต๋๋ค.
3. take
take ์กฐํฉ๊ธฐ๋ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์์ ์ฒ์ n๊ฐ์ ๊ฐ๋ง ๋ฐฉ์ถํฉ๋๋ค.
async function* take(iterable, n) {
let i = 0;
for await (const value of iterable) {
if (i < n) {
yield value;
i++;
} else {
return;
}
}
}
// Example:
async function* infiniteNumberGenerator() {
let i = 0;
while (true) {
await new Promise(resolve => setTimeout(resolve, 50));
yield i++;
}
}
(async () => {
const firstFiveNumbers = take(infiniteNumberGenerator(), 5);
for await (const value of firstFiveNumbers) {
console.log(value); // Output: 0, 1, 2, 3, 4 (with delays)
}
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: take๋ ์ ์ฌ์ ์ผ๋ก ๋ฌดํํ ์คํธ๋ฆผ์ ์ ํ๋ ์ผ๋ถ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ ์๋๋ฆฌ์ค์์ ์ ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ์ฌ ์ธํ๋ผ ์ฉ๋์ด ๋ค์ํ ์ฌ๋ฌ ์ง์ญ์ ์์คํ
์ ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ์ง ์๋๋ก API ์์ฒญ์ด๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ๋ฅผ ์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
4. drop
drop ์กฐํฉ๊ธฐ๋ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์์ ์ฒ์ n๊ฐ์ ๊ฐ์ ๊ฑด๋๋ฐ๊ณ ๋๋จธ์ง ๊ฐ์ ๋ฐฉ์ถํฉ๋๋ค.
async function* drop(iterable, n) {
let i = 0;
for await (const value of iterable) {
if (i >= n) {
yield value;
} else {
i++;
}
}
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
(async () => {
const remainingNumbers = drop(numberGenerator(), 2);
for await (const value of remainingNumbers) {
console.log(value); // Output: 3, 4, 5
}
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: take์ ์ ์ฌํ๊ฒ, drop์ ๋์ฉ๋ ๋ฐ์ดํฐ์
์ ๋ค๋ฃฐ ๋ ์ ์ฉํ ์ ์์ต๋๋ค. ์ ์ธ๊ณ์ ์ผ๋ก ๋ถ์ฐ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ด ์๋ ๊ฒฝ์ฐ, drop์ ์ฌ์ฉํ์ฌ ํ์์คํฌํ๋ ์ํ์ค ๋ฒํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฏธ ์ฒ๋ฆฌ๋ ๋ ์ฝ๋๋ฅผ ๊ฑด๋๋ฐ์ด ์ฌ๋ฌ ์ง๋ฆฌ์ ์์น ๊ฐ์ ํจ์จ์ ์ธ ๋๊ธฐํ๋ฅผ ๋ณด์ฅํ ์ ์์ต๋๋ค.
5. reduce
reduce ์กฐํฉ๊ธฐ๋ ์ฃผ์ด์ง ๋ฆฌ๋์ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๊ฐ๋ค์ ๋จ์ผ ๊ฐ์ผ๋ก ๋์ ํฉ๋๋ค. ์ด๋ ๋ฐฐ์ด์ reduce ํจ์์ ์ ์ฌํฉ๋๋ค.
async function reduce(iterable, reducer, initialValue) {
let accumulator = initialValue;
for await (const value of iterable) {
accumulator = await reducer(accumulator, value);
}
return accumulator;
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
}
async function sum(a, b) {
await new Promise(resolve => setTimeout(resolve, 50));
return a + b;
}
(async () => {
const total = await reduce(numberGenerator(), sum, 0);
console.log(total); // Output: 15 (after delays)
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: reduce๋ฅผ ์ฌ์ฉํ ๋, ํนํ ๊ธ์ต ๋๋ ๊ณผํ ๊ณ์ฐ์ ๊ฒฝ์ฐ, ์ฌ๋ฌ ํ๋ซํผ๊ณผ ๋ก์ผ์ผ์์ ๋ฐ์ํ ์ ์๋ ์ ๋ฐ๋ ๋ฐ ๋ฐ์ฌ๋ฆผ ์ค๋ฅ์ ์ ์ํด์ผ ํฉ๋๋ค. ์ฌ์ฉ์์ ์ง๋ฆฌ์ ์์น์ ๊ด๊ณ์์ด ์ ํํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ์ ์ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ธฐ์ ์ ์ฌ์ฉํ์ญ์์ค.
6. flatMap
flatMap ์กฐํฉ๊ธฐ๋ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๊ฐ ๋ฐฉ์ถํ๋ ๊ฐ ๊ฐ์ ํจ์๋ฅผ ์ ์ฉํ๋ฉฐ, ์ด ํจ์๋ ๋ค๋ฅธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ฒฐ๊ณผ๋ก ๋์จ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ค์ ๋จ์ผ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ก ํํํํฉ๋๋ค.
async function* flatMap(iterable, fn) {
for await (const value of iterable) {
const innerIterable = await fn(value);
for await (const innerValue of innerIterable) {
yield innerValue;
}
}
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
async function* duplicate(x) {
await new Promise(resolve => setTimeout(resolve, 50));
yield x;
yield x;
}
(async () => {
const duplicatedNumbers = flatMap(numberGenerator(), duplicate);
for await (const value of duplicatedNumbers) {
console.log(value); // Output: 1, 1, 2, 2, 3, 3 (with delays)
}
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: flatMap์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๊ด๋ จ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ผ๋ก ๋ณํํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ณธ ์คํธ๋ฆผ์ ๊ฐ ์์๊ฐ ๊ตญ๊ฐ๋ฅผ ๋ํ๋ด๋ ๊ฒฝ์ฐ, ๋ณํ ํจ์๋ ํด๋น ๊ตญ๊ฐ ๋ด์ ๋์ ๋ชฉ๋ก์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๋ค์ํ ๊ธ๋ก๋ฒ ์์ค์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ API ์๋ ์ ํ ๋ฐ ์ง์ฐ ์๊ฐ์ ์ธ์งํ๊ณ ์ ์ ํ ์บ์ฑ ๋๋ ์ค๋กํ๋ง ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ์ญ์์ค.
7. forEach
forEach ์กฐํฉ๊ธฐ๋ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๊ฐ ๊ฐ์ ๋ํด ์ ๊ณต๋ ํจ์๋ฅผ ํ ๋ฒ์ฉ ์คํํฉ๋๋ค. ๋ค๋ฅธ ์กฐํฉ๊ธฐ์ ๋ฌ๋ฆฌ ์๋ก์ด ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ์ง ์์ผ๋ฉฐ, ๋ถ์ ํจ๊ณผ(side effects)๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
async function forEach(iterable, fn) {
for await (const value of iterable) {
await fn(value);
}
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
async function logNumber(x) {
await new Promise(resolve => setTimeout(resolve, 50));
console.log("Processing:", x);
}
(async () => {
await forEach(numberGenerator(), logNumber);
console.log("Done processing.");
// Output: Processing: 1, Processing: 2, Processing: 3, Done processing. (with delays)
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: forEach๋ ๋ก๊น
, ์๋ฆผ ์ ์ก ๋๋ UI ์์ ์
๋ฐ์ดํธ์ ๊ฐ์ ์์
์ ํธ๋ฆฌ๊ฑฐํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ ์ธ๊ณ์ ์ผ๋ก ๋ถ์ฐ๋ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ด๋ฅผ ์ฌ์ฉํ ๋, ๋ค๋ฅธ ์๊ฐ๋๋ ๋ค์ํ ๋คํธ์ํฌ ์กฐ๊ฑด์์ ์์
์ ์ํํ ๋์ ์ํฅ์ ๊ณ ๋ คํ์ญ์์ค. ์ ๋ขฐ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ฌ์๋ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ์ญ์์ค.
8. toArray
toArray ์กฐํฉ๊ธฐ๋ ์
๋ ฅ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋ชจ๋ ๊ฐ์ ๋ฐฐ์ด๋ก ์์งํฉ๋๋ค.
async function toArray(iterable) {
const result = [];
for await (const value of iterable) {
result.push(value);
}
return result;
}
// Example:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
}
(async () => {
const numbersArray = await toArray(numberGenerator());
console.log(numbersArray); // Output: [1, 2, 3]
})();
๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ: ์ ์ฌ์ ์ผ๋ก ๋ฌดํํ๊ฑฐ๋ ๋งค์ฐ ํฐ ์คํธ๋ฆผ์ ๋ค๋ฃฐ ๋๋ ๋ฉ๋ชจ๋ฆฌ ๊ณ ๊ฐ๋ก ์ด์ด์ง ์ ์์ผ๋ฏ๋ก toArray๋ฅผ ์ ์คํ๊ฒ ์ฌ์ฉํ์ญ์์ค. ๋งค์ฐ ํฐ ๋ฐ์ดํฐ์
์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ์ฒญํฌ ๋จ์๋ก ์ฒ๋ฆฌํ๊ฑฐ๋ ์คํธ๋ฆฌ๋ฐ API๋ฅผ ์ฌ์ฉํ๋ ๋ฑ์ ๋์์ ๊ณ ๋ คํ์ญ์์ค. ์ ์ธ๊ณ์ ์ฌ์ฉ์ ์์ฑ ์ฝํ
์ธ ๋ฅผ ๋ค๋ฃจ๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด์ ์ ์ฅํ ๋ ๋ค์ํ ๋ฌธ์ ์ธ์ฝ๋ฉ๊ณผ ํ
์คํธ ๋ฐฉํฅ์ฑ์ ์ธ์งํด์ผ ํฉ๋๋ค.
์กฐํฉ๊ธฐ ๊ตฌ์ฑํ๊ธฐ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ์ ์ง์ ํ ํ์ ์กฐํฉ ๊ฐ๋ฅ์ฑ์ ์์ต๋๋ค. ์ฌ๋ฌ ์กฐํฉ๊ธฐ๋ฅผ ํจ๊ป ์ฐ๊ฒฐํ์ฌ ๋ณต์กํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๋ง๋ค ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์ซ์ ์คํธ๋ฆผ์ ๋ฐฉ์ถํ๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๊ฐ ์๊ณ , ํ์๋ฅผ ๊ฑธ๋ฌ๋ด๊ณ ์ง์๋ฅผ ์ ๊ณฑํ ๋ค์ ์ฒซ ์ธ ๊ฐ์ ๊ฒฐ๊ณผ๋ง ๊ฐ์ ธ์ค๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ด
์๋ค. filter, map, take ์กฐํฉ๊ธฐ๋ฅผ ์กฐํฉํ์ฌ ์ด๋ฅผ ๋ฌ์ฑํ ์ ์์ต๋๋ค:
async function* numberGenerator() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
yield 6;
yield 7;
yield 8;
yield 9;
yield 10;
}
async function isEven(x) {
return x % 2 === 0;
}
async function square(x) {
return x * x;
}
async function* filter(iterable, predicate) {
for await (const value of iterable) {
if (await predicate(value)) {
yield value;
}
}
}
async function* map(iterable, fn) {
for await (const value of iterable) {
yield await fn(value);
}
}
async function* take(iterable, n) {
let i = 0;
for await (const value of iterable) {
if (i < n) {
yield value;
i++;
} else {
return;
}
}
}
(async () => {
const pipeline = take(map(filter(numberGenerator(), isEven), square), 3);
for await (const value of pipeline) {
console.log(value); // Output: 4, 16, 36
}
})();
์ด๋ ๊ฐ๋จํ๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์กฐํฉ๊ธฐ๋ค์ ๊ฒฐํฉํ์ฌ ์ ๊ตํ ๋ฐ์ดํฐ ๋ณํ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
์ค์ฉ์ ์ธ ์ ์ฉ ์ฌ๋ก
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๋ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์๋๋ฆฌ์ค์์ ์ ์ฉํฉ๋๋ค:
- ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ: ์ผ์, ์์ ๋ฏธ๋์ด ํผ๋ ๋๋ ๊ธ์ต ์์ฅ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ ์ฒ๋ฆฌ.
- ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ: ๋ฐ์ดํฐ ์จ์ดํ์ฐ์ง ๋ฐ ๋ถ์์ ์ํ ETL(์ถ์ถ, ๋ณํ, ์ ์ฌ) ํ์ดํ๋ผ์ธ ๊ตฌ์ถ.
- ๋น๋๊ธฐ API: ๋ฐ์ดํฐ๋ฅผ ์ฒญํฌ ๋จ์๋ก ๋ฐํํ๋ API์ ๋ฐ์ดํฐ ์๋น.
- UI ์ ๋ฐ์ดํธ: ๋น๋๊ธฐ ์ด๋ฒคํธ์ ๊ธฐ๋ฐํ ์ฌ์ฉ์ ์ธํฐํ์ด์ค ์ ๋ฐ์ดํธ.
- ํ์ผ ์ฒ๋ฆฌ: ๋์ฉ๋ ํ์ผ์ ์ฒญํฌ ๋จ์๋ก ์ฝ๊ณ ์ฒ๋ฆฌ.
์์: ์ค์๊ฐ ์ฃผ์ ๋ฐ์ดํฐ
์ ์ธ๊ณ์ ์ค์๊ฐ ์ฃผ์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ ๊ธ์ต ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ๋ค์ํ ์ฃผ์์ ๊ฐ๊ฒฉ ์ ๋ฐ์ดํธ ์คํธ๋ฆผ์ ํฐ์ปค ์ฌ๋ณผ๋ก ์๋ณํ์ฌ ์์ ํฉ๋๋ค. ์ด ์คํธ๋ฆผ์ ํํฐ๋งํ์ฌ ๋ด์ ์ฆ๊ถ ๊ฑฐ๋์(NYSE)์์ ๊ฑฐ๋๋๋ ์ฃผ์์ ์ ๋ฐ์ดํธ๋ง ํ์ํ ๋ค์ ๊ฐ ์ฃผ์์ ์ต์ ๊ฐ๊ฒฉ์ ํ์ํ๊ณ ์ถ์ต๋๋ค.
async function* stockDataStream() {
// Simulate a stream of stock data from different exchanges
const exchanges = ['NYSE', 'NASDAQ', 'LSE', 'HKEX'];
const symbols = ['AAPL', 'MSFT', 'GOOG', 'TSLA', 'AMZN', 'BABA'];
while (true) {
await new Promise(resolve => setTimeout(resolve, Math.random() * 500));
const exchange = exchanges[Math.floor(Math.random() * exchanges.length)];
const symbol = symbols[Math.floor(Math.random() * symbols.length)];
const price = Math.random() * 2000;
yield { exchange, symbol, price };
}
}
async function isNYSE(stock) {
return stock.exchange === 'NYSE';
}
async function* filter(iterable, predicate) {
for await (const value of iterable) {
if (await predicate(value)) {
yield value;
}
}
}
async function toLatestPrices(iterable) {
const latestPrices = {};
for await (const stock of iterable) {
latestPrices[stock.symbol] = stock.price;
}
return latestPrices;
}
async function forEach(iterable, fn) {
for await (const value of iterable) {
await fn(value);
}
}
(async () => {
const nyseStocks = filter(stockDataStream(), isNYSE);
const updateUI = async (stock) => {
//Simulate UI update
console.log(`UI updated with : ${JSON.stringify(stock)}`)
await new Promise(resolve => setTimeout(resolve, Math.random() * 100));
}
forEach(nyseStocks, updateUI);
})();
์ด ์๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , ๊ด๋ จ ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฑธ๋ฌ๋ด๊ณ , ์ต์ ์ ๋ณด๋ก UI๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ค์ ์๋๋ฆฌ์ค์์๋ ์๋ฎฌ๋ ์ด์ ๋ ์ฃผ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ค์๊ฐ ๊ธ์ต ๋ฐ์ดํฐ ํผ๋ ์ฐ๊ฒฐ๋ก ๋์ฒดํ ๊ฒ์ ๋๋ค.
์ฌ๋ฐ๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ํํ๊ธฐ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๋ฅผ ์ง์ ๊ตฌํํ ์๋ ์์ง๋ง, ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ง ์กฐํฉ๊ธฐ์ ๊ธฐํ ์ ์ฉํ ์ ํธ๋ฆฌํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ช ๊ฐ์ง ์ธ๊ธฐ ์๋ ์ต์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- IxJS (Reactive Extensions for JavaScript): ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ๋ฐ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๊ฐ๋ ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ํจ๊ป ์ฌ์ฉํ ์ ์๋ ํ๋ถํ ์ฐ์ฐ์ ์ธํธ๋ฅผ ํฌํจํฉ๋๋ค.
- zen-observable: ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ก ์ฝ๊ฒ ๋ณํํ ์ ์๋ Observable์ ์ํ ๊ฒฝ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- Most.js: ๋ ๋ค๋ฅธ ๊ณ ์ฑ๋ฅ ๋ฐ์ํ ์คํธ๋ฆผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
์ฌ๋ฐ๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ํํ๋ ๊ฒ์ ํน์ ์๊ตฌ์ฌํญ๊ณผ ์ ํธ๋์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ๋ฒ๋ค ํฌ๊ธฐ, ์ฑ๋ฅ, ํน์ ์กฐํฉ๊ธฐ์ ๊ฐ์ฉ์ฑ๊ณผ ๊ฐ์ ์์๋ฅผ ๊ณ ๋ คํ์ญ์์ค.
์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๊น๋ํ๊ณ ์กฐํฉ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง๋ง, ํนํ ๋์ฉ๋ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ ๋๋ ์ฑ๋ฅ ์ํฅ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๋ถํ์ํ ์ค๊ฐ ์ดํฐ๋ ์ดํฐ ํผํ๊ธฐ: ๊ฐ ์กฐํฉ๊ธฐ๋ ์๋ก์ด ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์์ฑํ์ฌ ์ค๋ฒํค๋๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. ํ์ดํ๋ผ์ธ์ ์กฐํฉ๊ธฐ ์๋ฅผ ์ต์ํํ์ญ์์ค.
- ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ: ๋ฐ์ดํฐ์ ํฌ๊ธฐ์ ํน์ฑ์ ์ ํฉํ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ์ญ์์ค.
- ์ญ์(Backpressure) ๊ณ ๋ ค: ๋ฐ์ดํฐ ์์ค๊ฐ ์๋น์๊ฐ ์ฒ๋ฆฌํ ์ ์๋ ์๋๋ณด๋ค ๋น ๋ฅด๊ฒ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ, ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํ๋ก๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ญ์ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ์ญ์์ค.
- ์ฝ๋ ๋ฒค์น๋งํน: ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ ์ฝ๋๋ฅผ ์ต์ ํํ์ญ์์ค.
๋ชจ๋ฒ ์ฌ๋ก
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ ์์ ์ ์ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์กฐํฉ๊ธฐ๋ฅผ ์๊ณ ์ง์ค์ ์ผ๋ก ์ ์ง: ๊ฐ ์กฐํฉ๊ธฐ๋ ๋จ์ผํ๊ณ ์ ์ ์๋ ๋ชฉ์ ์ ๊ฐ์ ธ์ผ ํฉ๋๋ค.
- ๋จ์ ํ ์คํธ ์์ฑ: ์กฐํฉ๊ธฐ๊ฐ ์์๋๋ก ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ฒ ์ ํ ํ ์คํธํ์ญ์์ค.
- ์ค๋ช ์ ์ธ ์ด๋ฆ ์ฌ์ฉ: ์กฐํฉ๊ธฐ์ ๊ธฐ๋ฅ์ ๋ช ํํ๊ฒ ๋ํ๋ด๋ ์ด๋ฆ์ ์ ํํ์ญ์์ค.
- ์ฝ๋ ๋ฌธ์ํ: ์กฐํฉ๊ธฐ ๋ฐ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๋ํ ๋ช ํํ ๋ฌธ์๋ฅผ ์ ๊ณตํ์ญ์์ค.
- ์ค๋ฅ ์ฒ๋ฆฌ ๊ณ ๋ ค: ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์๊ธฐ์น ์์ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ๊ตฌํํ์ญ์์ค.
๊ฒฐ๋ก
์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ์กฐํฉ๊ธฐ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ณํํ๊ณ ์กฐ์ํ๋ ๊ฐ๋ ฅํ๊ณ ์ฐ์ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ์ ๊ธฐ๋ณธ์ ์ดํดํ๊ณ ์กฐํฉ๊ธฐ์ ํ์ ํ์ฉํจ์ผ๋ก์จ, ์ต์ ์น ๋ฐ ์๋ฒ์ฌ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ํจ์จ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๊ณํ ๋, ์ง์ ์ผ๋ก ์ธ๊ณ์ ์ธ ์๋ฃจ์ ์ ๋ง๋ค๊ธฐ ์ํด ๋ค์ํ ์ง์ญ๊ณผ ๋ฌธํ์ ๊ฑธ์น ๋ฐ์ดํฐ ํ์, ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ฑ๋ฅ์ ๊ธ๋ก๋ฒ ์ํฅ์ ๊ณ ๋ คํ์ญ์์ค.