JavaScript ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ผ๋ก ๋น๋๊ธฐ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ๋ง์คํฐํ์ธ์. ์ต์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์คํธ๋ฆผ ์ฒ๋ฆฌ, ์ค๋ฅ ์ฒ๋ฆฌ, ์ฑ๋ฅ ์ต์ ํ๋ฅผ ๋ฐฐ์ฐ์ธ์.
JavaScript ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง: ๋น๋๊ธฐ ์คํธ๋ฆผ ๋ฆฌ์์ค ๊ด๋ฆฌ
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ต์ JavaScript ๊ฐ๋ฐ์ ์ด์์ผ๋ก, ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ I/O ์์ ๊ณผ ๋ณต์กํ ๋ฐ์ดํฐ ํ๋ฆ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ํด์ค๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ ๋น๋๊ธฐ ๋ฆฌ์์ค, ํนํ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๋ค๋ฃฐ ๋ ์ด๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ ๋๊ตฌ ๋ชจ์์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ ์ด ์์ง์ ๊ฐ๋ , ๊ธฐ๋ฅ, ์ค์ ์ ์ฉ ์ฌ๋ก๋ฅผ ๊น์ด ํ๊ณ ๋ค์ด, ์ฌ๋ฌ๋ถ์ด ๊ฒฌ๊ณ ํ๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ ๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ํ์ํ ์ง์์ ๊ฐ์ถ๋๋ก ๋์ต๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ์ ๋๋ ์ดํฐ ์ดํดํ๊ธฐ
์์ง ์์ฒด์ ๋ํด ์์๋ณด๊ธฐ ์ ์, ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ์ ๋๋ ์ดํฐ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ ํต์ ์ธ ๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์์ ์ดํฐ๋ ์ดํฐ๋ ์ํ์ค์ ์์์ ํ ๋ฒ์ ํ๋์ฉ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ ์ด ๊ฐ๋ ์ ๋น๋๊ธฐ ์์ ์ผ๋ก ํ์ฅํ์ฌ, ์ฆ์ ์ฌ์ฉ ๊ฐ๋ฅํ์ง ์์ ์ ์๋ ์คํธ๋ฆผ์์ ๊ฐ์ ๊ฒ์ํ ์ ์๊ฒ ํด์ค๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ(asynchronous iterator)๋ next()
๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ๊ฐ์ฒด์ด๋ฉฐ, ์ด ๋ฉ์๋๋ ๋ ๊ฐ์ง ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ก ํด์(resolve)๋๋ Promise๋ฅผ ๋ฐํํฉ๋๋ค:
value
: ์ํ์ค์ ๋ค์ ๊ฐ.done
: ์ํ์ค๊ฐ ๋ชจ๋ ์์ง๋์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ ๊ฐ.
๋น๋๊ธฐ ์ ๋๋ ์ดํฐ(asynchronous generator)๋ async
์ yield
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ๊ฐ์ ์ํ์ค๋ฅผ ์์ฑํ๋ ํจ์์
๋๋ค. ์ด ํจ์๋ ์๋์ผ๋ก ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
๋ค์์ 1๋ถํฐ 5๊น์ง์ ์ซ์๋ฅผ ์์ฑํ๋ ๊ฐ๋จํ ๋น๋๊ธฐ ์ ๋๋ ์ดํฐ ์์ ์ ๋๋ค:
async function* numberGenerator(limit) {
for (let i = 1; i <= limit; i++) {
await new Promise(resolve => setTimeout(resolve, 100)); // ๋น๋๊ธฐ ์์
์ ์๋ฎฌ๋ ์ด์
ํฉ๋๋ค
yield i;
}
}
// ์ฌ์ฉ ์:
(async () => {
for await (const number of numberGenerator(5)) {
console.log(number);
}
})();
๋ฆฌ์์ค ์์ง์ด ํ์ํ ์ด์
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ์ ๋๋ ์ดํฐ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์์ ์ ์ํ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ง๋ง, ๋ฆฌ์์ค๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ด๋ฆฌํ๋ ๋ฐ ์ด๋ ค์์ ์ด๋ํ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ์์ ์ด ํ์ํ ์ ์์ต๋๋ค:
- ์ ์ ์ ๋ฆฌ ๋ณด์ฅ: ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์คํธ๋ฆผ์ด ๋ ์ด์ ํ์ํ์ง ์์ ๋ ํ์ผ ํธ๋ค, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๋๋ ๋คํธ์ํฌ ์์ผ๊ณผ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ํด์ ํฉ๋๋ค.
- ์ฐ์ํ ์ค๋ฅ ์ฒ๋ฆฌ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๋จ์ํค์ง ์๊ณ ๋น๋๊ธฐ ์์ ์์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ์ ํํฉ๋๋ค.
- ์ฑ๋ฅ ์ต์ ํ: ๋ฐ์ดํฐ๋ฅผ ์ฒญํฌ ๋จ์๋ก ์ฒ๋ฆฌํ๊ณ ๋ถํ์ํ ๋ฒํผ๋ง์ ํผํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๊ณผ ์ง์ฐ ์๊ฐ์ ์ต์ํํฉ๋๋ค.
- ์ทจ์ ์ง์ ์ ๊ณต: ์๋น์๊ฐ ๋ ์ด์ ์คํธ๋ฆผ์ด ํ์ ์๋ค๋ ์ ํธ๋ฅผ ๋ณด๋ด๊ณ ๊ทธ์ ๋ฐ๋ผ ๋ฆฌ์์ค๋ฅผ ํด์ ํ ์ ์๋๋ก ํฉ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ ๋น๋๊ธฐ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ๋ ์ผ๋ จ์ ์ ํธ๋ฆฌํฐ์ ์ถ์ํ๋ฅผ ์ ๊ณตํ์ฌ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ ์ฃผ์ ๊ธฐ๋ฅ
์ด ์์ง์ ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค:
1. ๋ฆฌ์์ค ํ๋ ๋ฐ ํด์
์์ง์ ๋ฆฌ์์ค๋ฅผ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ์ ์ฐ๊ฒฐํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ์ดํฐ๋ ์ดํฐ๊ฐ ์๋น๋๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด, ์์ง์ ์ฐ๊ด๋ ๋ฆฌ์์ค๊ฐ ํต์ ๋๊ณ ์์ธก ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ํด์ ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
์์ : ํ์ผ ์คํธ๋ฆผ ๊ด๋ฆฌํ๊ธฐ
const fs = require('fs').promises;
async function* readFileLines(filePath) {
let fileHandle;
try {
fileHandle = await fs.open(filePath, 'r');
const stream = fileHandle.createReadStream({ encoding: 'utf8' });
const reader = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new LineStream());
for await (const line of reader) {
yield line;
}
} finally {
if (fileHandle) {
await fileHandle.close();
}
}
}
// ์ฌ์ฉ๋ฒ:
(async () => {
try {
for await (const line of readFileLines('data.txt')) {
console.log(line);
}
} catch (error) {
console.error('ํ์ผ ์ฝ๊ธฐ ์ค๋ฅ:', error);
}
})();
//์ด ์์ ๋ 'fs' ๋ชจ๋์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ํ์ผ์ ์ด๊ณ ํ ์ค์ฉ ์ฝ์ต๋๋ค.
//'try...finally' ๋ธ๋ก์ ์ฝ๋ ๋์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ผ๋ ํ์ผ์ด ๋ซํ๋๋ก ๋ณด์ฅํฉ๋๋ค.
์ด๋ ๋จ์ํ๋ ์ ๊ทผ ๋ฐฉ์์ ๋ณด์ฌ์ค๋๋ค. ๋ฆฌ์์ค ์์ง์ ์ด ๊ณผ์ ์ ๋ ์ถ์์ ์ด๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌํ๋ฉฐ, ์ ์ฌ์ ์ธ ์ค๋ฅ์ ์ทจ์ ์ ํธ๋ฅผ ๋ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
2. ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ ํ
์์ง์ ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๋น๋๊ธฐ ์์ ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ ์ฒ๋ฆฌํ ์ ์๊ฒ ํฉ๋๋ค. ๋ํ ์ค๋ฅ๊ฐ ์ดํฐ๋ ์ดํฐ์ ์๋น์์๊ฒ ์ ํ๋๋๋ก ๋ณด์ฅํ์ฌ ๋ฌด์ธ๊ฐ ์๋ชป๋์์์ ๋ช ํํ๊ฒ ์๋ ค์ค๋๋ค.
์์ : API ์์ฒญ์์ ์ค๋ฅ ์ฒ๋ฆฌํ๊ธฐ
async function* fetchUsers(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ์ค๋ฅ! ์ํ: ${response.status}`);
}
const data = await response.json();
for (const user of data) {
yield user;
}
} catch (error) {
console.error('์ฌ์ฉ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ ์ค๋ฅ:', error);
throw error; // ์ค๋ฅ๋ฅผ ๋ค์ ๋์ ธ ์ ํํฉ๋๋ค
}
}
// ์ฌ์ฉ๋ฒ:
(async () => {
try {
for await (const user of fetchUsers('https://api.example.com/users')) {
console.log(user);
}
} catch (error) {
console.error('์ฌ์ฉ์ ์ฒ๋ฆฌ ์คํจ:', error);
}
})();
//์ด ์์ ๋ API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋์ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
//'try...catch' ๋ธ๋ก์ fetch ์์
์ค ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํฉ๋๋ค.
//ํธ์ถํ๋ ํจ์๊ฐ ์คํจ๋ฅผ ์ธ์งํ๋๋ก ์ค๋ฅ๋ฅผ ๋ค์ ๋์ง๋๋ค.
3. ์ทจ์ ์ง์
์์ง์ ์๋น์๊ฐ ์คํธ๋ฆผ ์ฒ๋ฆฌ ์์ ์ ์ทจ์ํ๊ณ , ์ฐ๊ด๋ ๋ฆฌ์์ค๋ฅผ ํด์ ํ๋ฉฐ, ์ถ๊ฐ ๋ฐ์ดํฐ ์์ฑ์ ๋ฐฉ์งํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๋ ์ฅ๊ธฐ ์คํ ์คํธ๋ฆผ์ ๋ค๋ฃจ๊ฑฐ๋ ์๋น์๊ฐ ๋ ์ด์ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ์ง ์์ ๋ ํนํ ์ ์ฉํฉ๋๋ค.
์์ : AbortController๋ฅผ ์ฌ์ฉํ ์ทจ์ ๊ตฌํ
async function* fetchData(url, signal) {
try {
const response = await fetch(url, { signal });
if (!response.ok) {
throw new Error(`HTTP ์ค๋ฅ! ์ํ: ${response.status}`);
}
const reader = response.body.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
yield value;
}
} finally {
reader.releaseLock();
}
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch ์ค๋จ๋จ');
} else {
console.error('๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์ค๋ฅ:', error);
throw error;
}
}
}
// ์ฌ์ฉ๋ฒ:
(async () => {
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => {
controller.abort(); // 3์ด ํ fetch๋ฅผ ์ทจ์ํฉ๋๋ค
}, 3000);
try {
for await (const chunk of fetchData('https://example.com/large-data', signal)) {
console.log('์์ ๋ ์ฒญํฌ:', chunk);
}
} catch (error) {
console.error('๋ฐ์ดํฐ ์ฒ๋ฆฌ ์คํจ:', error);
}
})();
//์ด ์์ ๋ AbortController๋ฅผ ์ฌ์ฉํ ์ทจ์๋ฅผ ๋ณด์ฌ์ค๋๋ค.
//AbortController๋ฅผ ์ฌ์ฉํ๋ฉด fetch ์์
์ ์ทจ์ํด์ผ ํ๋ค๋ ์ ํธ๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
//'fetchData' ํจ์๋ 'AbortError'๋ฅผ ํ์ธํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ฒ๋ฆฌํฉ๋๋ค.
4. ๋ฒํผ๋ง ๋ฐ ์ญ์
์์ง์ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ฒํผ๋ง ๋ฐ ์ญ์(backpressure) ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ฒํผ๋ง์ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ๋์ ํ ์ ์์ผ๋ฉฐ, ์ญ์์ ์๋น์๊ฐ ์์ฐ์์๊ฒ ๋ ์ด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ค๋น๊ฐ ๋์ง ์์์์ ์๋ฆด ์ ์๊ฒ ํฉ๋๋ค.
์์ : ๊ฐ๋จํ ๋ฒํผ ๊ตฌํํ๊ธฐ
async function* bufferedStream(source, bufferSize) {
const buffer = [];
for await (const item of source) {
buffer.push(item);
if (buffer.length >= bufferSize) {
yield buffer.splice(0, bufferSize);
}
}
if (buffer.length > 0) {
yield buffer;
}
}
// ์ฌ์ฉ ์:
(async () => {
async function* generateNumbers() {
for (let i = 1; i <= 10; i++) {
await new Promise(resolve => setTimeout(resolve, 50));
yield i;
}
}
for await (const chunk of bufferedStream(generateNumbers(), 3)) {
console.log('์ฒญํฌ:', chunk);
}
})();
//์ด ์์ ๋ ๊ฐ๋จํ ๋ฒํผ๋ง ๋ฉ์ปค๋์ฆ์ ๋ณด์ฌ์ค๋๋ค.
//'bufferedStream' ํจ์๋ ์์ค ์คํธ๋ฆผ์ ํญ๋ชฉ์ ๋ฒํผ์ ์์งํฉ๋๋ค.
//๋ฒํผ๊ฐ ์ง์ ๋ ํฌ๊ธฐ์ ๋๋ฌํ๋ฉด ๋ฒํผ์ ๋ด์ฉ์ ์์ฑํฉ๋๋ค.
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง ์ฌ์ฉ์ ์ด์
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ๋ฌ ์ด์ ์ด ์์ต๋๋ค:
- ๋จ์ํ๋ ๋ฆฌ์์ค ๊ด๋ฆฌ: ๋น๋๊ธฐ ๋ฆฌ์์ค ๊ด๋ฆฌ์ ๋ณต์ก์ฑ์ ์ถ์ํํ์ฌ ๊ฒฌ๊ณ ํ๊ณ ์ ๋ขฐํ ์ ์๋ ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
- ํฅ์๋ ์ฝ๋ ๊ฐ๋ ์ฑ: ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ์ํ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ API๋ฅผ ์ ๊ณตํ์ฌ ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ๊ณ ์ ์ง๋ณด์ํ ์ ์์ต๋๋ค.
- ๊ฐํ๋ ์ค๋ฅ ์ฒ๋ฆฌ: ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ์ค๋ฅ๊ฐ ํฌ์ฐฉ๋๊ณ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์ต์ ํ๋ ์ฑ๋ฅ: ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ฒํผ๋ง ๋ฐ ์ญ์ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค.
- ํฅ์๋ ์ฌ์ฌ์ฉ์ฑ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ ์ฝ๊ฒ ํตํฉํ ์ ์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๋ณด์ผ๋ฌํ๋ ์ดํธ ๊ฐ์: ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ์ํด ์์ฑํด์ผ ํ๋ ๋ฐ๋ณต์ ์ธ ์ฝ๋์ ์์ ์ต์ํํฉ๋๋ค.
์ค์ฉ์ ์ธ ์ ์ฉ ์ฌ๋ก
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์๋๋ฆฌ์ค์์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค:
- ํ์ผ ์ฒ๋ฆฌ: ๋์ฉ๋ ํ์ผ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ฝ๊ณ ์๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ: ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฟผ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์คํธ๋ฆฌ๋ฐํฉ๋๋ค.
- ๋คํธ์ํฌ ํต์ : ๋คํธ์ํฌ ์์ฒญ๊ณผ ์๋ต์ ์ฒ๋ฆฌํฉ๋๋ค.
- ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ: ๋ฐ์ดํฐ๋ฅผ ์ฒญํฌ ๋จ์๋ก ์ฒ๋ฆฌํ๋ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํฉ๋๋ค.
- ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ: ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌํํฉ๋๋ค.
์์ : IoT ์ฅ์น์ ์ผ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
์์ฒ ๊ฐ์ IoT ์ฅ์น์์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ์๋๋ฆฌ์ค๋ฅผ ์์ํด ๋ณด์ธ์. ๊ฐ ์ฅ์น๋ ์ผ์ ํ ๊ฐ๊ฒฉ์ผ๋ก ๋ฐ์ดํฐ ํฌ์ธํธ๋ฅผ ๋ณด๋ด๊ณ , ์ด ๋ฐ์ดํฐ๋ฅผ ์ค์๊ฐ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์ด์์ ๊ฐ์งํ๊ณ ๊ฒฝ๊ณ ๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
// IoT ์ฅ์น๋ก๋ถํฐ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ ์๋ฎฌ๋ ์ด์
async function* simulateIoTData(numDevices, intervalMs) {
let deviceId = 1;
while (true) {
await new Promise(resolve => setTimeout(resolve, intervalMs));
const deviceData = {
deviceId: deviceId,
temperature: 20 + Math.random() * 15, // ์จ๋ 20์์ 35 ์ฌ์ด
humidity: 50 + Math.random() * 30, // ์ต๋ 50์์ 80 ์ฌ์ด
timestamp: new Date().toISOString(),
};
yield deviceData;
deviceId = (deviceId % numDevices) + 1; // ์ฅ์น ์ํ
}
}
// ์ด์ ๊ฐ์ง ํจ์ (๊ฐ๋จํ ์์ )
function detectAnomalies(data) {
const { temperature, humidity } = data;
if (temperature > 32 || humidity > 75) {
return { ...data, anomaly: true };
}
return { ...data, anomaly: false };
}
// ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ ๋ก๊น
ํจ์ (์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ผ๋ก ๋์ฒด)
async function logData(data) {
// ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ธฐ ์๋ฎฌ๋ ์ด์
await new Promise(resolve => setTimeout(resolve, 10));
console.log('๋ฐ์ดํฐ ๋ก๊น
:', data);
}
// ๋ฉ์ธ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ
(async () => {
const numDevices = 5;
const intervalMs = 500;
const dataStream = simulateIoTData(numDevices, intervalMs);
try {
for await (const rawData of dataStream) {
const processedData = detectAnomalies(rawData);
await logData(processedData);
}
} catch (error) {
console.error('ํ์ดํ๋ผ์ธ ์ค๋ฅ:', error);
}
})();
//์ด ์์ ๋ IoT ์ฅ์น์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ์๋ฎฌ๋ ์ด์
ํ๊ณ , ์ด์์ ๊ฐ์งํ๋ฉฐ, ๋ฐ์ดํฐ๋ฅผ ๋ก๊น
ํฉ๋๋ค.
//๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
//์ค์ ์๋๋ฆฌ์ค์์๋ ์๋ฎฌ๋ ์ด์
๋ ํจ์๋ฅผ ์ค์ ๋ฐ์ดํฐ ์์ค, ์ด์ ๊ฐ์ง ์๊ณ ๋ฆฌ์ฆ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ํธ์์ฉ์ผ๋ก ๋์ฒดํด์ผ ํฉ๋๋ค.
์ด ์์ ์์ ์์ง์ IoT ์ฅ์น๋ก๋ถํฐ์ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ์คํธ๋ฆผ์ด ๋ ์ด์ ํ์ํ์ง ์์ ๋ ๋ฆฌ์์ค๊ฐ ํด์ ๋๊ณ ์ค๋ฅ๊ฐ ์ฐ์ํ๊ฒ ์ฒ๋ฆฌ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ๋ํ ์ญ์์ ๊ตฌํํ์ฌ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ด ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ์๋ํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ์ฌ์ฉ๋ ์๋ ์์ต๋๋ค.
์ฌ๋ฐ๋ฅธ ์์ง ์ ํํ๊ธฐ
์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์์ง์ ์ ํํ ๋ ๋ค์ ์์๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- ๊ธฐ๋ฅ: ์์ง์ด ๋ฆฌ์์ค ํ๋ ๋ฐ ํด์ , ์ค๋ฅ ์ฒ๋ฆฌ, ์ทจ์ ์ง์, ๋ฒํผ๋ง, ์ญ์๊ณผ ๊ฐ์ด ํ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๊น?
- ์ฑ๋ฅ: ์์ง์ ์ฑ๋ฅ๊ณผ ํจ์จ์ฑ์ด ์ข์ต๋๊น? ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๊ณผ ์ง์ฐ ์๊ฐ์ ์ต์ํํฉ๋๊น?
- ์ฌ์ฉ ํธ์์ฑ: ์์ง์ด ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ํตํฉํ๊ธฐ ์ฝ์ต๋๊น? ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ API๋ฅผ ์ ๊ณตํฉ๋๊น?
- ์ปค๋ฎค๋ํฐ ์ง์: ์์ง์ด ํฌ๊ณ ํ๋ฐํ ์ปค๋ฎค๋ํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๊น? ๋ฌธ์ํ๊ฐ ์ ๋์ด ์๊ณ ์ง์์ด ์ ๋ฉ๋๊น?
- ์ข ์์ฑ: ์์ง์ ์ข ์์ฑ์ ๋ฌด์์ ๋๊น? ๊ธฐ์กด ํจํค์ง์ ์ถฉ๋์ ์ผ์ผํฌ ์ ์์ต๋๊น?
- ๋ผ์ด์ ์ค: ์์ง์ ๋ผ์ด์ ์ค๋ ๋ฌด์์ ๋๊น? ํ๋ก์ ํธ์ ํธํ๋ฉ๋๊น?
์์ ๋ง์ ์์ง์ ๊ตฌ์ถํ๋ ๋ฐ ์๊ฐ์ ์ค ์ ์๋ ์ ์ฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ผ๋ถ ์ธ๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค (์ด ๊ฐ๋ ์์ ์ข ์์ฑ์ ์๋):
- Itertools.js: ๋น๋๊ธฐ ๋๊ตฌ๋ฅผ ํฌํจํ ๋ค์ํ ์ดํฐ๋ ์ดํฐ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Highland.js: ์คํธ๋ฆผ ์ฒ๋ฆฌ ์ ํธ๋ฆฌํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- RxJS: ๋น๋๊ธฐ ์คํธ๋ฆผ๋ ์ฒ๋ฆฌํ ์ ์๋ ๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
๋๋ง์ ๋ฆฌ์์ค ์์ง ๊ตฌ์ถํ๊ธฐ
๊ธฐ์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ข ์ข ์ ์ตํ์ง๋ง, ๋ฆฌ์์ค ๊ด๋ฆฌ์ ์๋ฆฌ๋ฅผ ์ดํดํ๋ฉด ํน์ ์๊ตฌ์ ๋ง๋ ๋ง์ถคํ ์๋ฃจ์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ธ ๋ฆฌ์์ค ์์ง์ ๋ค์์ ํฌํจํ ์ ์์ต๋๋ค:
- ๋ฆฌ์์ค ๋ํผ(Resource Wrapper): ๋ฆฌ์์ค(์: ํ์ผ ํธ๋ค, ์ฐ๊ฒฐ)๋ฅผ ์บก์ํํ๊ณ ํ๋ ๋ฐ ํด์ ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ ๊ฐ์ฒด์ ๋๋ค.
- ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ๋ฐ์ฝ๋ ์ดํฐ(Async Iterator Decorator): ๊ธฐ์กด ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ๋ฆฌ์์ค ๊ด๋ฆฌ ๋ก์ง์ผ๋ก ๊ฐ์ธ๋ ํจ์์ ๋๋ค. ์ด ๋ฐ์ฝ๋ ์ดํฐ๋ ๋ฐ๋ณต ์ ์ ๋ฆฌ์์ค๊ฐ ํ๋๋๊ณ ์ดํ(๋๋ ์ค๋ฅ ์)์ ํด์ ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
- ์ค๋ฅ ์ฒ๋ฆฌ: ๋ฐ๋ณต ๋ฐ ๋ฆฌ์์ค ํด์ ์ค ์์ธ๋ฅผ ํฌ์ฐฉํ๊ธฐ ์ํด ๋ฐ์ฝ๋ ์ดํฐ ๋ด์ ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค.
- ์ทจ์ ๋ก์ง: AbortController ๋๋ ์ ์ฌํ ๋ฉ์ปค๋์ฆ๊ณผ ํตํฉํ์ฌ ์ธ๋ถ ์ทจ์ ์ ํธ๊ฐ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฐ์ํ๊ฒ ์ข ๋ฃํ๊ณ ๋ฆฌ์์ค๋ฅผ ํด์ ํ ์ ์๋๋ก ํฉ๋๋ค.
๋น๋๊ธฐ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฌ๊ณ ์ฑ๊ณผ ์ฑ๋ฅ์ ๋ณด์ฅํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด์ญ์์ค:
- ํญ์ ๋ฆฌ์์ค ํด์ : ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ผ๋ ๋ ์ด์ ํ์ํ์ง ์์ ๋ฆฌ์์ค๋ ๋ฐ๋์ ํด์ ํ์ญ์์ค.
try...finally
๋ธ๋ก์ด๋ ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ ์ฌ์ฉํ์ฌ ์ ์์ ์ ๋ฆฌ๋๋๋ก ํ์ญ์์ค. - ์ฐ์ํ ์ค๋ฅ ์ฒ๋ฆฌ: ๋น๋๊ธฐ ์์ ์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ ์ฒ๋ฆฌํ์ญ์์ค. ์ค๋ฅ๋ฅผ ์ดํฐ๋ ์ดํฐ์ ์๋น์์๊ฒ ์ ํํ์ญ์์ค.
- ๋ฒํผ๋ง ๋ฐ ์ญ์ ์ฌ์ฉ: ๋ฒํผ๋ง๊ณผ ์ญ์์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ์ญ์์ค.
- ์ทจ์ ์ง์ ๊ตฌํ: ์๋น์๊ฐ ์คํธ๋ฆผ ์ฒ๋ฆฌ ์์ ์ ์ทจ์ํ ์ ์๋๋ก ํ์ฉํ์ญ์์ค.
- ์ฝ๋ ์ฒ ์ ํ ํ ์คํธ: ๋น๋๊ธฐ ์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๊ณ ๋ฆฌ์์ค๊ฐ ์ ๋๋ก ๊ด๋ฆฌ๋๋์ง ํ์ธํ๊ธฐ ์ํด ํ ์คํธํ์ญ์์ค.
- ๋ฆฌ์์ค ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง: ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฆฌ์์ค ์ฌ์ฉ๋์ ๋ชจ๋ํฐ๋งํ์ฌ ์ ์ฌ์ ์ธ ๋์๋ ๋นํจ์จ์ฑ์ ์๋ณํ์ญ์์ค.
- ์ ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ ์์ง ์ฌ์ฉ ๊ณ ๋ ค: ๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง๊ณผ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ๊ฐ์ํํ๊ณ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ์ค์ผ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
๋น๋๊ธฐ ์ดํฐ๋ ์ดํฐ ํฌํผ ๋ฆฌ์์ค ์์ง์ JavaScript์์ ๋น๋๊ธฐ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ๋ฆฌ์์ค ํ๋ ๋ฐ ํด์ , ์ค๋ฅ ์ฒ๋ฆฌ, ์ฑ๋ฅ ์ต์ ํ๋ฅผ ๋จ์ํํ๋ ์ผ๋ จ์ ์ ํธ๋ฆฌํฐ์ ์ถ์ํ๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ, ์ด ์์ง์ ๊ฒฌ๊ณ ํ๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ ๋น๋๊ธฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๋์์ ์ค ์ ์์ต๋๋ค. ์ด ๊ธ์์ ์ค๋ช ํ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ ์ฉํจ์ผ๋ก์จ, ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ์ ํ์ฉํ์ฌ ๊ด๋ฒ์ํ ๋ฌธ์ ์ ๋ํ ํจ์จ์ ์ด๊ณ ํ์ฅ ๊ฐ๋ฅํ ์๋ฃจ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ์ ์ ํ ์์ง์ ์ ํํ๊ฑฐ๋ ์์ ๋ง์ ์์ง์ ๊ตฌํํ๋ ๊ฒ์ ํ๋ก์ ํธ์ ํน์ ์๊ตฌ ์ฌํญ๊ณผ ์ ์ฝ ์กฐ๊ฑด์ ์ ์คํ๊ฒ ๊ณ ๋ คํด์ผ ํฉ๋๋ค. ๊ถ๊ทน์ ์ผ๋ก ๋น๋๊ธฐ ๋ฆฌ์์ค ๊ด๋ฆฌ๋ฅผ ๋ง์คํฐํ๋ ๊ฒ์ ๋ชจ๋ ํ๋ JavaScript ๊ฐ๋ฐ์์๊ฒ ํต์ฌ ๊ธฐ์ ์ ๋๋ค.