์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 | 31 |
- ๋ฐฑ์ค
- BFS
- MVVM
- realm
- CollectionView
- ํจ์คํธ์บ ํผ์ค
- tableView
- BOJ
- RxSwift
- raywenderlich
- arkit
- swift
- ios
- reactorkit
- combine
- Lv2
- Flutter
- designpattern
- Swfit
- ํ๋ก๊ทธ๋๋จธ์ค
- SwiftUI
- Kuring
- visionOS
- UIKit
- Xcode
- SnapKit
- TCA
- node.js
- XCTest
- rxcocoa
- Today
- Total
lgvv98
[Node.js] #3 ๋ ธ๋ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ ๋ณธ๋ฌธ
#3 ๋ ธ๋ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ
# REPL ์ฌ์ฉํ๊ธฐ
Read ์ฝ๊ณ , Eval ํ๊ฐํ๊ณ , Print ์ถ๋ ฅํ๊ณ , Loop ์ข ๋ฃํ ๋๊น์ง ๋ฐ๋ณต์์ ์๊ธ์๋ง ๋ฐ์ ์ด์ผ๊ธฐ ํจ.
์ฝ์์ node๋ผ๊ณ ์ ๋ ฅํ๋ฉด ๋๋ค.
์ข ๋ฃํ๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ์ปจํธ๋กค + C ๋๋ฒ ํน์, .exit์ ์ ๋ ฅํ์ฌ ์ข ๋ฃ.
# JS ํ์ผ ์คํ
ํด๋น ํ์ผ ์์ฑํ ์ฝ์์ node {ํด๋นํ์ผ} ์ ๋ ฅํ๊ธฐ ํ์ฅ์๋ ์๋ต.
# ๋ชจ๋๋ก ๋ง๋ค๊ธฐ
๋ ธ๋๋ ๋๊ฐ์ง ๋ชจ๋ ์ฌ์ฉ CommonJS์ ECMAScript.
- CommonJS: ์ด๊ฑด ํ์ค ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋์ ์๋์ง๋ง ํ์ค ๋์ค๊ธฐ ์ด์ ๋ถํฐ ์ฐ์ฌ์ ๋๋ฆฌ ์ฐ์.
- ECMAScript(ES ๋ชจ๋): ๊ณต์์ ์ธ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋ชจ๋. ES ๋ชจ๋์ด ํ์ค์ผ๋ก ์ ํด์ง๋ฉด์, ๋ธ๋ผ์ฐ์ ์ ๋ ธ๋ ๋ชจ๋์์ ๊ฐ์ ๋ชจ๋ ํ์์ ์ฌ์ฉํ ์ ์๋ค๋ ์ฅ์ .
# CommonJS
// var.js
const odd = 'cjs odd'
const even = 'cjs even'
// ์ด ๋ฐฉ๋ฒ์ ๊ฐ์ฒด๋ง ๊ฐ๋ฅ, func.js์ฒ๋ผ ํจ์๋ฅผ ๋ฃ์ ๊ฒฝ์ฐ์๋ ๋ถ๊ฐ.
exports.even = 'CJS ์ง์';
exports.odd = 'CJS ํ์';
// module.exports = {
// odd,
// even
// }
๋๊ฐ์ ๋ณ์๋ฅผ ์ ์ธํ๊ณ modlue.exports๋ฅผ ํตํด ๋์ .
์ด๋ ๊ฒํ๋ฉด ์ด์ ๋ชจ๋๋ก์จ ๊ธฐ๋ฅํจ.
์๋ ์ฝ๋๋ ์ฐธ์กฐํ๋ ๋ฐฉ์
// func.js
// ๋ถ๋ฌ์ฌ ํ์ผ์ ๊ฒฝ๋ก์ฅ์ ํ์ฅ์(js, json)์ ์๋ต ๊ฐ๋ฅ.
// index.js๋ ์๋ต ๊ฐ๋ฅ
const { odd, even } = require('./var'); // ๋ถ๋ฌ์ฌ ํ์ผ์ ๊ฒฝ๋ก
function checkOddOrEven(num) {
if (num % 2) {
return odd;
}
return even;
}
module.exports = checkOddOrEven;
// index.js
const { odd, even } = require('./var');
const checkNumber = require('./func');
function checkStringOddOrEven(str) {
if (str.length % 2) {
return odd;
}
return even;
}
console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));
require ํจ์์์ ๋ถ๋ฌ์ฌ ๋ชจ๋์ ๊ฒฝ๋ก๋ฅผ ์ ์ด์ค.
- exports ๊ฐ์ฒด ์ฌ์ฉ์ ์ฃผ์์ฌํญ
๊ฐ์ฒด๋ง ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก, ํจ์๋ฅผ ๋์ ํ ๊ฒฝ์ฐ์๋ ์ด ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์ ์์.
- ๋ ธ๋์ this๋ ์ข ๋ค๋ฆ.
๋๋ถ๋ถ์ this๋ ๋ธ๋ผ์ฐ์ ์ ๋์ผํ๊ฒ global์ ๊ฐ๋ฅดํค๋, ์ต์์ ์ค์ฝํ๋ module.exports๋ฅผ ๊ฐ๋ฅดํจ๋ค.
// require.js
console.log('require๊ฐ ๊ฐ์ฅ ์์ ์ค์ง ์์๋ ๋ฉ๋๋ค.');
module.exports = '์ ๋ฅผ ์ฐพ์๋ณด์ธ์.';
require('./var');
console.log('require.cache์
๋๋ค.'); // 1
console.log(require.cache); // 2
console.log('require.main์
๋๋ค.'); // 3
console.log(require.main === module); // 4
console.log(require.main.filename); // 5
1. ๊ทธ๋๋ก ์ถ๋ ฅ
2. ๋ ธ๋์์๋ ํ๋ฒ requireํ ํ์ผ์ require.cache์ ์ ์ฅ๋๋ฏ๋ก ๋ค์ ๋ฒ์ requireํ ๋๋ ์๋ก ๋ถ๋ฌ์ค์ง ์๊ณ ์บ์์ ์๋ ๊ฒ ์ฌ์ฉ.
3. ๊ทธ๋๋ก ์ถ๋ ฅ
4. require.main์ ๋ ธ๋ ์คํ ์ ์ฒซ ๋ชจ๋์ ๊ฐ๋ฅดํจ๋ค. ๋ฐ๋ผ์ ํ์ฌ๋ require.main์.
๋ฐ๋ผ์ ํ์ฌ require.main๊ณผ require.cache(module, ์บ์์์ ๋ถ๋ฌ์๊ธฐ ๋๋ฌธ์)๋ ๋์ผ.
๋ง์ฝ var.js์์ ํด๋น ์ฝ๋๋ฅผ ์คํํ๋ฉด false๋ก ๋ฐํ
5. ํ์ฌ ํ์ผ ๋ค์ ์๋ ค์ค.
๋ง์ฝ ๋ชจ๋ ๋ถ๋ฌ์ฌ ๋ ์ํ์ฐธ์กฐํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
// dep1.js
const dep2 = require('./dep2');
console.log('require dep2', dep2);
module.exports = () => {
console.log('dep2', dep2);
};
// dep2.js
const dep1 = require('./dep1');
console.log('require dep1', dep1);
module.exports = () => {
console.log('dep1', dep1);
};
//dep-run.js
const dep1 = require('./dep1');
const dep2 = require('./dep2');
dep1();
dep2();
dep1์ module.exports๊ฐ ํจ์๊ฐ ์๋๋ผ ๋น ๊ฐ์ฒด๋ก ํ์.
์ํ์ฐธ์กฐ์ ๊ฒฝ์ฐ์๋ ์ํ์ฐธ์กฐ๋๋ ๋์์ ๋น ๊ฐ์ฒด๋ก ๋ง๋ค์ด๋ฒ๋ฆผ. ์๋ฌ๊ฐ ์๋ ์๋์ ๋ฐ์์ํด.
# ECMAScript
// var.mjs
export const odd = 'cjs odd'
export const even = 'cjs even'
// func.mjs
import { odd, even } from './var';
function checkOddOrEven(num) {
if (num % 2) { // ํ์๋ฉด
return odd;
}
return even;
}
export default checkOddOrEven;
// index.mjs
import { odd, even } from './var.mjs';
import checkNumber from './func.mjs';
// ๐ก const { odd, even } = require('./var');
// ๐ก const checkNumber = require('./func');
function checkStringOddOrEven(str) {
if (str.length % 2) {
return odd;
}
return even;
}
console.log(checkNumber(10));
console.log(checkStringOddOrEven('hello'));
require์ exports, module.exports๊ฐ ๊ฐ๊ฐ import, export ,export default๋ก ๋ณ๊ฒฝ๋์๋ค.
ํ์ผ ํ์ฅ์๋ js์์ mjs๋ก ๋ณ๊ฒฝ๋์์.
ํ์ฅ์๋ฅผ js๋ก ํ๊ณ import ์ฌ์ฉ์ ์๋ฌ ๋ฐ์ํฉ๋๋ค.
๋ง์ฝ ํ์ฅ์ js๋ฅผ ์ฌ์ฉํ๋ฉด์ ES๋ชจ๋์ ์ฌ์ฉํ๋ ค๋ฉด package.json์ type: "module" ์์ฑ์ ๋ฃ์ผ๋ฉด ๋๋ค.
CommonJS ๋ชจ๋๊ณผ๋ ๋ค๋ฅด๊ฒ ํ์ผ ๊ฒฝ๋ก์์ js, mjs ๊ฐ์ ํ์ฅ์๋ ์๋ตํ ์ ์์. ํด๋ ๋ด๋ถ์์ index.js๋ ์๋ต ๋ถ๊ฐ.
# ๋ค์ด๋ด๋ฏน ์ํฌํธ
CommonJS์์๋ ๊ฐ๋ฅํ๋ ES ๋ชจ๋์์๋ ๋ถ๊ฐ.
์กฐ๊ฑด๋ถ๋ก ๋ชจ๋์ ๋ถ๋ฌ์ค๋ ๊ฒ์ ์๋ฏธ
// dynamic.js
const a = false;
if (a) {
require('./func');
}
console.log('์ฑ๊ณต');
// ์ถ๋ ฅ๊ฒฐ๊ณผ
์ฑ๊ณต
// dynamic.mjs
const a = false;
if (a) {
import './func.mjs' // SyntaxError: Unexpected string
}
console.log('์ฑ๊ณต');
์์์ require('./func');๋ ์คํ๋์ง ์์. ์ด์ฒ๋ผ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ชจ๋์ ๋ถ๋ฌ์ด.
ํ์ง๋ง ES ๋ชจ๋์ด ์๋์ฒ๋ผ์ ๊ฐ๋ฅํจ.
// dynamic.mjs
const a = true;
if (a) {
const m1 = await import('./func.mjs');
console.log(m1);
const m2 = await import('./var.mjs');
console.log(m2);
}
import๋ Pormise๋ฅผ ๋ฐํํ๊ธฐ์ await์ด๋ then์ ๋ถ์ฌ์ผ ํ๋ค.
์ ์ฝ๋์์๋ async๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๋๋๋ฐ, ๊ทธ ์ด์ ๋ ์ต์์ ์ค์ฝํ์์๋ async ์์ด๋ await ํ ์ ์๋ค.
# __filename, __dirname
๋ ธ๋์์๋ ํ์ผ ์ฌ์ด์ ๋ชจ๋ ๊ด๊ณ๊ฐ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์ ํ ใ ํ์ผ์ ๊ฒฝ๋ก๋ ํ์ผ๋ช ์ ์์์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
์ด ๋๊ฐ์ ํค์๋๋ก ๊ฒฝ๋ก์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค.
console.log(__filename); // C:\User\Desktop\Karrot\NodeJS\var.js
console.log(__dirname); // C:\User\Desktop\Karrot\NodeJS
์ฐธ๊ณ ๋ก ES๋ชจ๋์์๋ ์ ๋๊ฐ ์ฌ์ฉํ ์ ์๋ค. ๋์ import.meta.url๋ก ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์จ๋ค.
// filename.mjs
console.log(import.meta.url); // C:\User\Desktop\Karrot\NodeJS\var.js
console.log('__filename์ ์๋ฌ');
console.log(__filename);
CommonJS ๋ชจ๋์์ ์ฌ์ฉํ๋ require ํจ์๋ module ๊ฐ์ฒด๋ ๋ฐ๋ก ์ ์ธํ์ง ์์์ด๋ ์ฌ์ฉํ ์ ์์. ์ด๊ฒ ์ ๋๋๋ฉด ๋ ธ๋์์ ๊ธฐ๋ณธ์ ๊ธ๋ก ์ ๊ณตํ๋ ๋ด์ฅ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ
# global
๋ธ๋ผ์ฐ์ ์ window๊ฐ์ ์ ์ญ๊ฐ์ฒด
์ ์ญ๊ฐ์ฒด๋ผ๋ ํน์ฑ์ ํ์ฉํ์ผ ๊ฐ์ ๊ฐ๋จํ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ๋ ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค.
// globalA.js
module.exports = () => global.message;
// globalB.js
const A = require('./globalA');
global.message = '์๋
ํ์ธ์.';
console.log(A());
// ์ถ๋ ฅ๊ฒฐ๊ณผ
$ node globalB
์๋
ํ์ธ์.
# console
const string = 'abc';
const number = 1;
const boolean = true;
const obj = {
outside: {
inside: {
key: 'value',
},
},
};
console.time('์ ์ฒด์๊ฐ');
console.log('ํ๋ฒํ ๋ก๊ทธ์
๋๋ค ์ผํ๋ก ๊ตฌ๋ถํด ์ฌ๋ฌ ๊ฐ์ ์ฐ์ ์ ์์ต๋๋ค');
console.log(string, number, boolean);
console.error('์๋ฌ ๋ฉ์์ง๋ console.error์ ๋ด์์ฃผ์ธ์');
console.table([{ name: '์ ๋ก', birth: 1994 }, { name: 'hero', birth: 1988}]);
console.dir(obj, { colors: false, depth: 2 });
console.dir(obj, { colors: true, depth: 1 });
console.time('์๊ฐ์ธก์ ');
for (let i = 0; i < 100000; i++) {}
console.timeEnd('์๊ฐ์ธก์ ');
function b() {
console.trace('์๋ฌ ์์น ์ถ์ ');
}
function a() {
b();
}
a();
console.timeEnd('์ ์ฒด์๊ฐ');
- console.time(๋ ์ด๋ธ): console.timeEnd(๋ ์ด๋ธ)๊ณผ ๋์๋์ด ๊ฐ์ ๋ ์ด๋ธ์ ๊ฐ์ง time๊ณผ timeEnd ์ฌ์ด์ ์๊ฐ์ ์ธก์ .
- console.log(๋ด์ฉ): ํ๋ฒํ ๋ก๊ทธ๋ฅผ ์ฝ์์ ํ์ํฉ๋๋ค. console.log(๋ด์ฉ, ๋ด์ฉ ...)์ฒ๋ผ ๋ด์ฉ์ ๋์ ํ์๋ ๊ฐ๋ฅ.
- console.error(์๋ฌ ๋ด์ฉ): ์๋ฌ๋ฅผ ์ฝ์์ ํ์
- console.table(๋ฐฐ์ด): ๋ฐฐ์ด์ ์์๋ก ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๋ฃ์ผ๋ฉด, ๊ฐ์ฒด์ ์์ฑ๋ค์ด ํ ์ด๋ธ ํ์์ผ๋ก ํํ.
- console.dir(๊ฐ์ฒด, ์ต์ ): ๊ฐ์ฒด๋ฅผ ์ฝ์์ ํ์ํ ๋ ์ฌ์ฉ. ์ฒซ๋ฒ์งธ์ ๊ฐ์ฒด๋ฅผ ๋ฃ๊ณ ๋๋ฒ์งธ์ ์ธ์๋ฅผ ๋ฃ๋๋ค. ์ต์ ์ colors๋ฅผ true๋ก ํ๋ฉด ์ฝ์์ ์์ด ์ถ๊ฐ๋์ด ๋ณด๊ธฐ๊ฐ ํ๊ฒฐ ํธํด์ง๋๋ค. depth๋ ๊ฐ์ฒด ์์ ๊ฐ์ฒด๋ฅผ ๋ช ๋จ๊ณ๊น์ง ๋ณด์ฌ์ค์ง ๊ฒฐ์ ํ๋ค. ๊ธฐ๋ณธ๊ฐ์ 2.
- console.trace(๋ ์ด๋ธ): ์๋ฌ๊ฐ ์ด๋์ ๋ฐ์ํ๋์ง ์ถ์ ํ ์ ์๊ฒ ํ๋ค. ๋ณดํต์ ์๋ฌ ๋ฐ์์ ์์น๋ฅผ ์๋ ค์ฃผ๋ฏ๋ก ์ฃผ๋ก ์ฌ์ฉํ์ง ์์ง๋ง, ์์น๊ฐ ๋์ค์ง ์๋๋ค๋ฉด ์ฌ์ฉํ ๋ง ํ๋ค.
# ํ์ด๋จธ
- setTimeout(์ฝ๋ฐฑ ํจ์, ๋ฐ๋ฆฌ์ด): ์ฃผ์ด์ง ๋ฐ๋ฆฌ์ด(1000๋ถ์ 1์ด) ์ดํ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํํฉ๋๋ค.
- setInterval(์ฝ๋ฐฑ ํจ์, ๋ฐ๋ฆฌ์ด): ์ฃผ์ด์ง ๋ฐ๋ฆฌ์ด ์ดํ์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํํฉ๋๋ค.
- setImmediate(์ฝ๋ฐฑ ํจ์): ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฆ์ ์คํ.
์ด ํ์ด๋จธ ํจ์๋ค์ ๋ชจ๋ ์์ด๋๋ฅผ ๋ฐํ. ์์ด๋๋ฅผ ์ฌ์ฉํ๋ฉด ํ์ด๋จธ๋ฅผ ์ทจ์ํ ์๋ ์์.
- clearTimeout(์์ด๋): setTimeout์ ์ทจ์.
- clearInterval(์์ด๋): setInterval์ ์ทจ์.
- clearImmediate(์์ด๋): setImmediate์ ์ทจ์.
const timeout = setTimeout(() => { // 1.5์ด์ ํ๋ฒ ์คํ
console.log('1.5์ด ํ ์คํ');
}, 1500);
const interval = setInterval(() => { // 1์ด, 2์ด ์คํ
console.log('1์ด๋ง๋ค ์คํ');
}, 1000);
const timeout2 = setTimeout(() => { // ์คํ ์๋ผ
console.log('์คํ๋์ง ์์ต๋๋ค');
}, 3000);
setTimeout(() => { // 2.5์ด์ ๋๊ฐ ์ทจ์
clearTimeout(timeout2);
clearInterval(interval);
}, 2500);
const immediate = setImmediate(() => { // 0์ด์ ์คํ
console.log('์ฆ์ ์คํ');
});
const immediate2 = setImmediate(() => { // ์ฆ์ ์ทจ์๋์ด์ ๋ฏธ์คํ
console.log('์คํ๋์ง ์์ต๋๋ค');
});
clearImmediate(immediate2);
์ด๊ฑด ํ๋ํ๋ ๋ถ์ํด๋ณด๊ธฐ
setImmediate(์ฝ๋ฐฑ)๊ณผ setTimeout(์ฝ๋ฐฑ, 0)
- ๊ณตํต์ : ์ด๋ฒคํธ ๋ฃจํ ๊ฑฐ์น ๋ค ์ฆ์ ์คํ.
- ์ฐจ์ด์ : ํน์ํ ๊ฒฝ์ฐ์ setImmediate๋ setTimeout(์ฝ๋ฐฑ, 0)๋ณด๋ค ๋จผ์ ์คํ๋๋ค.
- ์๋ฅผ๋ค๋ฉด: ํ์ผ ์์คํ ์ ๊ทผ, ๋คํธ์ํน ๊ฐ์ I/O ์์ ์ ์ฝ๋ฐฑ ํจ์ ์์์ ํ์ด๋จธ๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ. ํ์ง๋ง ํญ์ ๋จผ์ ํธ์ถ๋๋๊ฑด ์๋.
ํท๊ฐ๋ฆฌ์ง ์๋๋ก setTimeout(์ฝ๋ฐฑ, 0) ์ฌ์ฉํ์ง ์๋๊ฑฐ ๊ถ์ฅ.
ํ์ด๋จธ๋ ์ฝ๋ฐฑ ๊ธฐ๋ฐ API์ง๋ง ํ๋ก๋ฏธ์ค ๋ฐฉ์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
// timerPromise.mjs
import { setTimeout, setInterval } from 'timers/promises'
await setTimeout(3000);
for await (const startTime of setInterval(1000, Date.now())) {
console.log('1์ด๋ง๋ค ์คํ', new Date(startTime));
}
// ์ถ๋ ฅ๊ฒฐ๊ณผ
3์ด ๋ค ์คํ
1์ด๋ง๋ค ์คํ
1์ด๋ง๋ค ์คํ
1์ด๋ง๋ค ์คํ
1์ด๋ง๋ค ์คํ
1์ด๋ง๋ค ์คํ
ํ๋ก๋ฏธ์ค ๊ธฐ๋ฐ์ด๋ฏ๋ก then ๋์ await์ ์ฌ์ฉํ๊ธฐ ์ํด ES ๋ชจ๋ ์ฌ์ฉํ์ผ๋ฉฐ, timers/promises๋ผ๋ ๋ชจ๋์์ setTimeout๊ณผ setInterval์ ์๋กญ๊ฒ ์ ๊ณต
# Process
ํ์ฌ ์คํ๋๊ณ ์๋ ๋ ธ๋ ํ๋ก์ธ์ค์ ๋ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์.
# Process.env
๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ค์ํ ์ ๋ณด ๊ทธ๋๋ก ์ ์ฅํด์ ํธ๋ฆฌ๋ฉด ํฐ ๋ฌธ์ ๋๋๊น env๋ก ์ ์ฅํ์.
๋ค๋ง process.env์ ์ํฌ๋ฆฟ ์์ด๋์ ์ํฌ๋ฆฟ ์ฝ๋๋ฅผ ์ง์ ๋ฃ์ผ๋ฉด ์ ๋ ์๋๋ค. ๋ฃ๋ ๋ฐฉ๋ฒ์ ์ด์์ฒด์ ๋ง๋ค ์ฐจ์ด๊ฐ ์๋ค.
const secretId = process.env.SECRET_ID;
const secretCode = process.env.SECRET_CODE;
# Process.nextTick(์ฝ๋ฐฑ)
์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋ค๋ฅธ ์ฝ๋ฐฑ ํจ์๋ค๋ณด๋ค nextTick์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฐ์ ์ ์ผ๋ก ์ฒ๋ฆฌ.
Promise์ resolve๋ ๋ค๋ฅธ ์ฝ๋ฐฑ๋ค๋ณด๋ค ์ฐ์ ์ ๋๋ค.
๊ทธ๋์ process.nextTick๊ณผ Promise๋ฅผ ๋ง์ดํฌ๋กํ์คํฌ๋ผ๊ณ ๋ฐ๋ก ๋ถ๋ฆ
setImmediate(() => {
console.log('immediate');
});
process.nextTick(() => {
console.log('nextTick');
});
setTimeout(() => {
console.log('timeout');
}, 0);
Promise.resolve().then(() => console.log('promise'));
// ์ถ๋ ฅ๊ฒฐ๊ณผ
nextTick
promise
timeout
immediate
๋ง์ดํฌ๋กํ์คํฌ๋ ์ฌ๊ทํธ์ถ์ด ๋๋ค.
# Process.exit
์คํ์ค์ธ ๋ ธ๋๋ฅผ ์ข ๋ฃ. ์๋ฒํ๊ฒฝ์์ ์ด ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฒ๊ฐ ๋ฉ์ถ๋ฏ๋ก ํน์ํ ์ํฉ์ ์ ์ธํ๊ณ ์๋ฒ์์ ์ ์ฌ์ฉํ์ง ์์.
# ๊ธฐํ ๋ด์ฅ ๊ฐ์ฒด
- URL, URLSearchParams
- AbortController, FormData, fetch, Headers, Request, Response, Event, EventTarget: ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉํ๋ API๊ฐ ๋ ธ๋์๋ ๋์ผํ๊ฒ ์์ฑ
- TextDecoder: Buffer๋ฅผ ๋ฌธ์์ด๋ก ๋ฐ๊ฟ.
- TextEncoder: ๋ฌธ์์ด์ Buffer๋ก ๋ฐ๊ฟ.
- WebAssembly: ์น์ด์ ๋ธ๋ฆฌ ์ฒ๋ฆฌ๋ฅผ ๋ด๋น.
# ๋ ธ๋ ๋ด์ฅ ๋ชจ๋ ์ฌ์ฉ
๋ชจ๋ ๊ณต์ ๋ฌธ์์ ์ ๋์ ์์ผ๋ ์ค์ํ ๊ฒ๋ค๋ง ์ ๋ฆฌ.
๋ ธ๋์ ๋ชจ๋์ ๋ ธ๋ ๋ฒ์ ๋ง๋ค ์ฐจ์ด๊ฐ ์๋ค.
ํด๋ผ์ด์ธํธ์ ์์ฒญํ ์ฃผ์์ ๋ํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๊ณ , os ์ ๋ณด๋ ์ ๊ทผํ ์ ์๋ค.
# os
๋๊ฐ๋ก ๋ถ๋ฌ์ฌ ์ ์์. require('os'); ๋๋ require('node.os');
const os = require('os');
console.log('์ด์์ฒด์ ์ ๋ณด---------------------------------');
console.log('os.arch():', os.arch());
console.log('os.platform():', os.platform());
console.log('os.type():', os.type());
console.log('os.uptime():', os.uptime());
console.log('os.hostname():', os.hostname());
console.log('os.release():', os.release());
console.log('๊ฒฝ๋ก------------------------------------------');
console.log('os.homedir():', os.homedir());
console.log('os.tmpdir():', os.tmpdir());
console.log('cpu ์ ๋ณด--------------------------------------');
console.log('os.cpus():', os.cpus());
console.log('os.cpus().length:', os.cpus().length);
console.log('๋ฉ๋ชจ๋ฆฌ ์ ๋ณด-----------------------------------');
console.log('os.freemem():', os.freemem());
console.log('os.totalmem():', os.totalmem());
์ด์์ฒด์ ๋ณ๋ก ๋ค๋ฅธ ์๋น์ค๋ฅผ ์ ๊ณตํ๊ณ ์ถ์ ๋๋ ๋ด๋ถ์์์ ๋น๋ฒํ๊ฒ ์ ๊ทผํ๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํฉ๋๋ค.
# path
ํด๋์ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ์ฝ๊ฒ ์กฐ์ํ๋๋ก ๋์์ฃผ๋ ๋ชจ๋. path๋ณ๋ก os๋ณ๋ก ๊ฒฝ๋ก ๊ตฌ๋ถ์๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ. ํฌ๊ฒ ์๋ ํ์ ๊ณผ POSIXํ์ ์ผ๋ก ๊ตฌ๋ถ. POSIX๋ ์ ๋์ค ๊ธฐ๋ฐ์ ์ด์์ฒด์ ๋ก ๋ฆฌ๋ ์ค๋ ๋งฅ์ด ์ฌ๊ธฐ์ ์ํจ.
- ์๋: C:\User\Karrot ... \๋ก ๊ตฌ๋ถ
- POSIX: /home/Karrot ... /๋ก ๊ตฌ๋ถ
const path = require('path');
const string = __filename;
console.log('path.sep:', path.sep);
console.log('path.delimiter:', path.delimiter);
console.log('------------------------------');
console.log('path.dirname():', path.dirname(string));
console.log('path.extname():', path.extname(string));
console.log('path.basename():', path.basename(string));
console.log('path.basename - extname:', path.basename(string, path.extname(string)));
console.log('------------------------------');
console.log('path.parse()', path.parse(string));
console.log('path.format():', path.format({
dir: 'C:\\users\\zerocho',
name: 'path',
ext: '.js',
}));
console.log('path.normalize():', path.normalize('C://users\\\\zerocho\\\path.js'));
console.log('------------------------------');
console.log('path.isAbsolute(C:\\):', path.isAbsolute('C:\\'));
console.log('path.isAbsolute(./home):', path.isAbsolute('./home'));
console.log('------------------------------');
console.log('path.relative():', path.relative('C:\\users\\zerocho\\path.js', 'C:\\'));
console.log('path.join():', path.join(__dirname, '..', '..', '/users', '.', '/zerocho'));
console.log('path.resolve():', path.resolve(__dirname, '..', 'users', '.', '/zerocho'));
join๊ณผ resolve๋ ๋น์ทํ์ง๋ง ์กฐ๊ธ ๋ค๋ฆ.
join('/a', '/b', 'c'); ๊ฒฐ๊ณผ: /a/b/c/ -> ์๋๊ฒฝ๋ก๋ก ์ฒ๋ฆฌ
resolve('/a', '/b', 'c'); ๊ฒฐ๊ณผ /b/c -> ์ ๋๊ฒฝ๋ก๋ก ์ธ์ํด์ ์์ ๊ฒฝ๋ก๋ฅผ ๋ฌด์
# url
์ธํฐ๋ท ์ฃผ์๋ฅผ ์ฝ๊ฒ ์กฐ์ํ๋๋ก ๋์์ฃผ๋ ๋ชจ๋
WHATWG(์น ํ์ค์ ์ ํ๋ ๋จ์ฒด์ ์ด๋ฆ)
const url = require('url');
const { URL } = url;
const myURL = new URL('http://www.gilbut.co.kr/book/bookList.aspx?sercate1=001001000#anchor');
console.log('new URL():', myURL); // ๋ถํด
console.log('url.format():', url.format(myURL)); // ์ฌ์กฐ๋ฆฝ
console.log('------------------------------');
const parsedUrl = url.parse('http://www.gilbut.co.kr/book/bookList.aspx?sercate1=001001000#anchor');
console.log('url.parse():', parsedUrl);
console.log('url.format():', url.format(parsedUrl));
searchParams
const { URL } = require('url');
const myURL = new URL('http://www.gilbut.co.kr/?page=3&limit=10&category=nodejs&category=javascript');
console.log('searchParams:', myURL.searchParams);
console.log('searchParams.getAll():', myURL.searchParams.getAll('category'));
console.log('searchParams.get():', myURL.searchParams.get('limit'));
console.log('searchParams.has():', myURL.searchParams.has('page'));
console.log('searchParams.keys():', myURL.searchParams.keys());
console.log('searchParams.values():', myURL.searchParams.values());
myURL.searchParams.append('filter', 'es3');
myURL.searchParams.append('filter', 'es5');
console.log(myURL.searchParams.getAll('filter'));
myURL.searchParams.set('filter', 'es6');
console.log(myURL.searchParams.getAll('filter'));
myURL.searchParams.delete('filter');
console.log(myURL.searchParams.getAll('filter'));
console.log('searchParams.toString():', myURL.searchParams.toString());
myURL.search = myURL.searchParams.toString();
//์ถ๋ ฅ๊ฒฐ๊ณผ
searchParams: URLSearchParams {
'page' => '3',
'limit' => '10',
'category' => 'nodejs',
'category' => 'javascript' }
searchParams.getAll(): [ 'nodejs', 'javascript' ]
searchParams.get(): 10
searchParams.has(): true
searchParams.keys(): URLSearchParams Iterator { 'page', 'limit', 'category', 'category' }
searchParams.values(): URLSearchParams Iterator { '3', '10', 'nodejs', 'javascript' }
[ 'es3', 'es5' ]
[ 'es6' ]
[]
# dns
DNS๋ฅผ ๋ค๋ฃฐ ๋ ์ฌ์ฉํ๋ ๋ชจ๋
์ฃผ๋ก ๋๋ฉ์ด๋ฅใน ํตํด IP๋ ๊ธฐํ DNS ์ ๋ณด๋ฅผ ์ป๊ณ ์ ํ ๋ ์ฌ์ฉ
import dns from 'dns/promises';
const ip = await dns.lookup('gilbut.co.kr');
console.log('IP', ip);
const a = await dns.resolve('gilbut.co.kr', 'A');
console.log('A', a);
const mx = await dns.resolve('gilbut.co.kr', 'MX');
console.log('MX', mx);
const cname = await dns.resolve('gilbut.co.kr', 'CNAME');
console.log('CNAME', cname);
const any = await dns.resolve('gilbut.co.kr', 'ANY');
console.log('ANY', any);
lookup์ด๋ resolve(๋๋ฉ์ธ)์ผ๋ก ์ป์ ์ ์์ ip์ฃผ์ ๊ฐ๋จํ๊ฒ.
MX, CNAME ๋ฑ์ ๋ ์ฝ๋๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, resolve(๋๋ฉ์ธ, ๋ ์ฝ๋ ์ด๋ฆ)์ผ๋ก ์กฐํํ๋ฉด ๋๋ค.
# crypto
๋ค์ํ ๋ฐฉ์์ผ๋ก ์ํธํํ๋ ๋ชจ๋. ๋ช๊ฐ์ง ๋ฉ์๋๋ ์ตํ๋๋ฉด ์ค์ ์๋น์ค์๋ ์์ฃผ ์ ์ฉ. ๊ณ ๊ฐ์ ๋น๋ฐ๋ฒํธ๋ ๋ฐ๋์ ์ํธํ ๊ทธ๋ ์ง ์์ผ๋ฉด ํดํน๋นํ๋ฉด ์ง์ง ๋์ฌ๊ณ ^_^
- ๋จ๋ฐฉํฅ ์ํธํ: ํ๋ฒ ์ํธํํ๋ฉด ๋ณตํธํํ ์ ์์. ํด์ ํจ์๋ผ๊ณ ๋ ๋ถ๋ฆผ.
- ๊ณ ๊ฐ์ ๋น๋ฐ๋ฒํธ๋ ๋ณตํธํ ํ ํ์๊ฐ ์์. ์ํธํํด์ DB์ ์ ์ฅํ๊ณ ๋ก๊ทธ์ธํ ๋๋ง๋ค ์ ๋ ฅ๋ฐ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฐ์ผ ์ํธํ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ํธํํ ํ DB์์ ๋น๊ตํ๋ฉด ๋ผ. ์๋ ๋น๋ฒ์ ์ํธํํด์ ์๋ฌด๋ฐ๋ ์ ์ฅ์๊ณ ๋น๊ตํจ.
- ์๋ฐฉํฅ ์ํธํ: ๋์นญํ ์ํธํ. ๋ฌธ์์ด ๋ณตํธํ๋ ๊ฐ๋ฅ.
# util
๊ฐ์ข ํธ์ ๊ธฐ๋ฅ์ ๋ชจ์๋ ๋ชจ๋. API๊ฐ ์ง์์ ์ผ๋ก ์ถ๊ฐ๋๊ณ ์์ผ๋ฉฐ, deprecated๋์ด ์ฌ๋ผ์ง๋ ๊ฒ๋ ์กด์ฌ.
์์ฃผ ์ฌ์ฉํ๋ ๋๊ฐ์ง ์๊ฐ
const util = require('util');
const crypto = require('crypto');
const dontUseMe = util.deprecate((x, y) => {
console.log(x + y);
}, 'dontUseMe ํจ์๋ deprecated๋์์ผ๋ ๋ ์ด์ ์ฌ์ฉํ์ง ๋ง์ธ์!');
dontUseMe(1, 2);
const randomBytesPromise = util.promisify(crypto.randomBytes);
randomBytesPromise(64)
.then((buf) => {
console.log(buf.toString('base64'));
})
.catch((error) => {
console.error(error);
});
- deprecated ์ฒ๋ฆฌ๋์์์ ์๋ฆผ,
- ์ฝ๋ฐฑ ํจํด์ ํ๋ก๋ง์ด์ฆ ํจํด์ผ๋ก ๋ฐ๊ฟ. ์ด๋ ๊ฒ ๋ฐ๊ฟ๋๋ฉด async/await๋ ์ฌ์ฉํ ์ ์์ด์ ์ข์.
# worker_threads
๋ ธ๋์์ ๋ฉํฐ ์ค๋ ๋ ๋ฐฉ์์ผ๋ก ์์ ํ๋ ๋ฐฉ๋ฒ์ ํด๋น ๋ชจ๋๋ก ๊ฐ๋ฅ
const {
Worker, isMainThread, parentPort,
} = require('worker_threads');
if (isMainThread) { // ๋ถ๋ชจ์ผ ๋
const worker = new Worker(__filename); // โ
1. ์์ปค ์ค๋ ๋ ์์ฑ
worker.on('message', message => console.log('from worker', message)); // ๐ก ๋ฆฌ์ค๋ ๋ฑ๋ก
worker.on('exit', () => console.log('worker exit')); โ
6. ์ข
๋ฃ ๋ฆฌ์ค๋ ๋ฐ์์ ์ฒ๋ฆฌ
worker.postMessage('ping'); // โ
2. ๋ฉ์์ง ๋ณด๋
} else { // ์์ปค์ผ ๋
parentPort.on('message', (value) => { // โ
3. ๋ฉ์์ง ๋ฐ์
console.log('from parent', value);
parentPort.postMessage('pong'); // โ
4. ๋ถ๋ชจ๋ก ๋ฉ์์ง ๋ณด๋
parentPort.close(); โ
4. ๋ถ๋ชจ ์ข
๋ฃ ์คํ
});
}
// ์คํ๊ฒฐ๊ณผ
from parent ping
from worker pong
worker exit
// ์คํ์ ๋ฆฌ
- ๋ถ๋ชจ์์๋ ์์ปค์ค๋ ๋ ์์ฑ ํ woker.postMessage๋ก ์์ปค์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋.
- ์์ปค๋
parentPort.on('message') ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ก๋ถํฐ ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ
parentPort.postMessage๋ก ๋ถ๋ชจ์๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋.
- ๋ถ๋ชจ๋ worker.on('message')๋ก ๋ฉ์์ง ๋ฐ์
์ฐธ๊ณ ๋ก ํ๋ฒ๋ง ๋ฐ์ผ๋ ค๋ฉด once('message')์ฌ์ฉ
- ์์ปค์์ on๋ฉ์๋๋ฅผ ์์ฉํ ๋ ์ง์ ์์ปค๋ฅผ ์ข
๋ฃํ๋ค๋ ๊ฒ์ ์ฃผ์
parentPort.close();ํ๋ฉด ์ข
๋ฃ
์๋๋ ์ฌ๋ฌ๊ฐ์ ์์ปค ์ค๋ ๋์ ๋ฐ์ดํฐ ๋๊ฒจ๋ณผ๊ฑฐ์.
const {
Worker, isMainThread, parentPort, workerData,
} = require('worker_threads');
if (isMainThread) { // ๋ถ๋ชจ์ผ ๋
const threads = new Set();
threads.add(new Worker(__filename, { // ํ์ผ ๋ค์์ ํ์ฌ ํ์ผ์์ ์์ปค์ค๋ ๋ ์คํ
workerData: { start: 1 }, // โ
๋๋ฒ์จฐ ์ธ์๋ก ์ํ๋ ๋ฐ์ดํฐ ๋ณด๋
}));
threads.add(new Worker(__filename, {
workerData: { start: 2 },
}));
for (let worker of threads) {
worker.on('message', message => console.log('from worker', message));
worker.on('exit', () => { // โ
์์๋ค์์ ๋๋ ค๋ฐ๋ ์๊ฐ ์ข
๋ฃ
threads.delete(worker);
if (threads.size === 0) {
console.log('job done'); // ์์ปค ๋๋ค ์ข
๋ฃ๋๋ฉด ์คํ
}
});
}
} else { // ์์ปค์ผ ๋
const data = workerData;
parentPort.postMessage(data.start + 100); // โ
ํ์ฌ ๋๊ฐ์ ์ค๋ ๋ ๋์๊ฐ๊ณ ์์ผ๋ฉฐ ๊ฐ๊ฐ ์ค๋ ๋์์ 100์ฉ ๋ํจ
}
// ์ถ๋ ฅ๊ฒฐ๊ณผ
from worker 101
from worker 102
job done
์ข ๋ ์ค์ง์ ์ธ ์์์ ๊ฐ์๋ฅผ ๊ตฌํ๋ ์์ ์ ์์ปค ์ค๋ ๋ ํตํด ํด๋ณด์.
const min = 2;
const max = 10000000;
const primes = [];
function findPrimes(start, range) {
let isPrime = true;
const end = start + range;
for (let i = start; i < end; i++) {
for (let j = min; j < Math.sqrt(end); j++) {
if (i !== j && i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.push(i);
}
isPrime = true;
}
}
console.time('prime');
findPrimes(min, max);
console.timeEnd('prime');
console.log(primes.length);
// ๊ฒฐ๊ณผ
prime: 8.475s
664579
pc ์ฑ๋ฅ์ ๋ฐ๋ผ ๋ค๋ฅด์ง๋ง ์๊ฐ ์๋นํ ์์
์ด๋ฒ์๋ ๋ฉํฐ์ค๋ ๋ฉ์ผ๋ก ํด๊ฒฐํด๋ณด๊ฒ ์.
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const min = 2;
let primes = [];
function findPrimes(start, range) {
let isPrime = true;
const end = start + range;
for (let i = start; i < end; i++) {
for (let j = min; j < Math.sqrt(end); j++) {
if (i !== j && i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.push(i);
}
isPrime = true;
}
}
if (isMainThread) {
const max = 10000000;
const threadCount = 8;
const threads = new Set();
const range = Math.ceil((max - min) / threadCount);
let start = min;
console.time('prime');
for (let i = 0; i < threadCount - 1; i++) {
const wStart = start;
threads.add(new Worker(__filename, { workerData: { start: wStart, range } }));
start += range;
}
threads.add(new Worker(__filename, { workerData: { start, range: range + ((max - min + 1) % threadCount) } }));
for (let worker of threads) {
worker.on('error', (err) => {
throw err;
});
worker.on('exit', () => {
threads.delete(worker);
if (threads.size === 0) {
console.timeEnd('prime');
console.log(primes.length);
}
});
worker.on('message', (msg) => {
primes = primes.concat(msg);
});
}
} else {
findPrimes(workerData.start, workerData.range);
parentPort.postMessage(primes);
}
// ๊ฒฐ๊ณผ
prime: 1.752s
664579
์ค๋ ๋์ ์ผ์ ๋๋ ์ฃผ์ด์ ๋ฐ๋ก ์ฒ๋ฆฌํ๊ฒ ํจ. ๋ฉํฐ ์ค๋ ๋ฉ์ ํ ๋๋ ์ผ์ ๋๋ ์ ์ฒ๋ฆฌํ๋๋ก ํ๋๊ฒ ์ ์ผ ์ด๋ ค์
8๋ฐฐ ๋นจ๋ผ์ง๋๊ฑฐ ์๋ ์ค๋ ๋ ์์ฑํ๊ณ ํต์ ํ๋๋ฐ๋ ๋น์ฉ์ด ๋ค์ด๊ฐ
# child_process
๋ ธ๋์์ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ ์คํํ๊ณ ์ถ๊ฑฐ๋ ๋ช ๋ น์ด๋ฅผ ์ํํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ ๋ชจ๋.
์ด ๋ชจ๋์ ํตํด ๋ค๋ฅธ ์ธ์ด์ ์ฝ๋๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ด๊ฐ์ ๋ฐ์ ์ ์์.
const exec = require('child_process').exec;
var process = exec('dir');
process.stdout.on('data', function(data) {
console.log(data.toString());
}); // ์คํ ๊ฒฐ๊ณผ
process.stderr.on('data', function(data) {
console.error(data.toString());
}); // ์คํ ์๋ฌ
๋ฆฌ๋ ์ค MyShell๊ตฌํ.(์ฌ๋ด์ด์ง๋ง ์ด์์ฒด์ ๊ณผ์ ๊ฐ ๋ง์ด ์ ๊ตฌํ์ด์์ ๊ทธ๋ ๋๋์ฒด ์ด๋ป๊ฒ ํ๊ฑธ๊น;)
exec('ls') ์ ๋ ฅํด๋ณด๊ธฐ
# ํ์ผ ์์คํ ์ ๊ทผ
fs ๋ชจ๋์ ํ์ผ ์์คํ ์ ์ ๊ทผํ๋ ๋ชจ๋. ์ฆ ํ์ผ CRUD๊ฐ๋ฅ. ์น ๋ธ๋ผ์ฐ์ ๋ js ์ฌ์ฉํ ๋ ์ผ๋ถ๋ฅผ ์ ์ธํ๊ณ ํ์ผ ์์คํ ๊ธ์ง๋์ด ์์ด์ js ๋ชจ๋์ด ๋ฏ์ค๊ฑฐ์.
// readme.txt
์ ๋ฅผ ์ฝ์ด์ฃผ์ธ์.
// readFile.js
const fs = require('fs');
fs.readFile('./readme.txt', (err, data) => {
if (err) {
throw err;
}
console.log(data);
console.log(data.toString());
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
<Buffer ec a0 80 eb a5 ...> // ์ฝ์ ๋ฐ์ดํฐ
์ ๋ฅผ ์ฝ์ด์ฃผ์ธ์. // ์ฝ์ ์คํธ๋ง
fs ๋ชจ๋ ๋ถ๋ฌ์จ ๋ค ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ง์ . ํ์ผ์ ๊ฒฝ๋ก๊ฐ ํ์ฌ ํ์ผ ๊ธฐ์ค์ด ์๋๋ผ node ๋ช ๋ น์ด๋ฅผ ์คํํ๋ ์ฝ์๊ธฐ์ค์ด๋ผ๋ ์ ์ ์ ์
์ง๊ธ์ ํฌ๊ฒ ์๊ด ์์ผ๋ ํด๋ ๋ด๋ถ์ ๋ค์ด์๋ ํ์ผ์ ์คํํ ๋ ๊ฒฝ๋ก ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์.
ํ์ผ์ ์ฝ์ ํ์ readFile๋ฉ์๋์ ์ธ์๋ก ๊ฐ์ด ๋ฃ์.
๊ฒฐ๊ณผ๋ฌผ์ ๋ฒํผ๋ผ๋ ํ์์ผ๋ก ์ ๊ณต.
fs๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ๋ฐฑํ์์ ๋ชจ๋์ด๋ผ ์ค๋ฌด์์ ์ฌ์ฉํ๊ธฐ ๋ถํธํจ. fs ๋ชจ๋์ ํ๋ก๋ฏธ์ค ํ์์ผ๋ก ๋ฐ๊ฟ์ฃผ๋ ๋ฐฉ๋ฒ ์ฌ์ฉ.
const fs = require('fs').promises;
fs.readFile('./readme.txt')
.then((data) => {
console.log(data);
console.log(data.toString());
})
.catch((err) => {
console.error(err);
});
fs๋ชจ๋์์ promise ์์ฑ์ ๋ถ๋ฌ์ค๋ฉด ํ๋ก๋ฏธ์ค ๊ธฐ๋ฐ์ fs ๋ชจ๋์ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
const fs = require('fs');
fs.writeFile('./writeme.txt', '๊ธ์ด ์
๋ ฅ๋ฉ๋๋ค', (err) => {
if (err) {
throw err;
}
fs.readFile('./writeme.txt', (err, data) => {
if (err) {
throw err;
}
console.log(data.toString());
});
});
# ๋๊ธฐ ๋ฉ์๋์ ๋น๋๊ธฐ ๋ฉ์๋
setTimeout๊ณผ ๊ฐ์ ํ์ด๋จธ์ process.nextTick ์ธ์๋ ๋ ธ๋๋ ๋๋ถ๋ถ์ ๋ฉ์๋๋ฅผ ๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ.
ํ์ง๋ง ๋ช๋ช ๋ฉ์๋๋ ๋๊ธฐ ๋ฐฉ์์ผ๋ก๋ ์ฌ์ฉ ๊ฐ๋ฅ. ํนํ fs ๋ชจ๋์ด ๊ทธ๋ฌํ ๋ฉ์๋๋ฅผ ๋ง์ด ๊ฐ๊ณ ์์ด. ๋ํ ์ธ์ ์ด๋ค ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ง ์์๋ณด์.
ํ์ผ ํ๋๋ฅผ ์ฌ๋ฌ๋ฒ ์ฝ์ด๋ณด์.
const fs = require('fs');
console.log('์์');
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('1๋ฒ', data.toString());
});
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('2๋ฒ', data.toString());
});
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('3๋ฒ', data.toString());
});
console.log('๋');
// ์ถ๋ ฅ๊ฒฐ๊ณผ
์์
๋
2๋ฒ ์ ๋ฅผ ์ฌ๋ฌ๋ฒ ์ฝ์ด๋ณด์ธ์.
3๋ฒ ์ ๋ฅผ ์ฌ๋ฌ๋ฒ ์ฝ์ด๋ณด์ธ์.
1๋ฒ ์ ๋ฅผ ์ฌ๋ฌ๋ฒ ์ฝ์ด๋ณด์ธ์.
์์๊ณผ ๋์ ์ ์ธํ๊ณ ๋ ์์๊ฐ ๋ค๋ฅผ ์ ์์ด.
๋น๋๊ธฐ ๋ฉ์๋ค์ ๋ฐฑ๊ทธ๋ผ์ด๋์ ํด๋น ํ์ผ์ ์ฝ์ผ๋ผ๊ณ ๋ง ์์ฒญํ๊ณ ๋ฐ๋ก ๋ค์ ์์ ์ผ๋ก ๋์ด๊ฐ.
const fs = require('fs');
console.log('์์');
let data = fs.readFileSync('./readme2.txt');
console.log('1๋ฒ', data.toString());
data = fs.readFileSync('./readme2.txt');
console.log('2๋ฒ', data.toString());
data = fs.readFileSync('./readme2.txt');
console.log('3๋ฒ', data.toString());
console.log('๋');
// ์ถ๋ ฅ๊ฒฐ๊ณผ
์์
1๋ฒ ์ ๋ฅผ ์ฝ์ด์ฃผ์ธ์.
2๋ฒ ์ ๋ฅผ ์ฝ์ด์ฃผ์ธ์.
3๋ฒ ์ ๋ฅผ ์ฝ์ด์ฃผ์ธ์.
๋
์ด๊ฑด ๋ญ ๋๋ฌด๋๋ ๋น์ฐํ๋ค.
๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก ํ๋ ์์๋ฅผ ์ ์งํ๊ณ ์ถ๋ค๋ฉด?
const fs = require('fs');
console.log('์์');
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('1๋ฒ', data.toString());
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('2๋ฒ', data.toString());
fs.readFile('./readme2.txt', (err, data) => {
if (err) {
throw err;
}
console.log('3๋ฒ', data.toString());
console.log('๋');
});
});
});
์ฝ๋ฐฑ ์ง์ฅ์ด ํผ์ณ์ง๋ ์์๊ฐ ์ด๊ธ๋๋ ์ผ์ ์๋ค.
์ฝ๋ฐฑ ์ง์ฅ์ Promise๋ async/await์ผ๋ก ์ด๋์ ๋ ํด๊ฒฐํ ์ ์์ต๋๋ค.
const fs = require('fs').promises;
console.log('์์');
fs.readFile('./readme2.txt')
.then((data) => {
console.log('1๋ฒ', data.toString());
return fs.readFile('./readme2.txt');
})
.then((data) => {
console.log('2๋ฒ', data.toString());
return fs.readFile('./readme2.txt');
})
.then((data) => {
console.log('3๋ฒ', data.toString());
console.log('๋');
})
.catch((err) => {
console.error(err);
});
# ๋ฒํผ์ ์คํธ๋ฆผ ์ดํดํ๊ธฐ
ํ์ผ์ ์ฐ๋ ๋ฐฉ์์๋ ํฌ๊ฒ ๋๊ฐ์ง๊ฐ ์์.
- ๋ฒํผ๋ฅผ ์ด์ฉ
- ์คํธ๋ฆผ์ ์ด์ฉ
๋ฒํผ๋ง์ ์์์ ์ฌ์ํ ์ ์์ ๋๊น์ง ๋ฐ์ดํฐ๋ฅผ ๋ชจ์ผ๋ ๋์
์คํธ๋ฆฌ๋ฐ์ ๋ฐฉ์ก์ธ์ ์ปดํจํฐ์์ ์์ฒญ์์ ์ปดํจํฐ๋ก ์์ ๋ฐ์ดํฐ๋ฅผ ์กฐ๊ธ์ฉ ์ ์กํ๋ ๋์
์คํธ๋ฆฌ๋ฐ ๊ณผ์ ์์ ๋ฒํผ๋ง ํ ์๋ ์์.
์ ์ก์ด ๋๋ฌด ๋๋ฆฌ๋ฉด ํ๋ฉด์ ๋ด๋ณด๋ด๊ธฐ๊น์ง ์ต์ํ์ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์์ผ ํ๊ณ
์์ ๋ฐ์ดํฐ๊ฐ ์ฌ์์๋๋ณด๋ค ๋๋ฌด ๋นจ๋ฆฌ ์ ์ก๋์ด๋ ๋ฏธ๋ฆฌ ์ ์ก๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๊ณต๊ฐ์ด ํ์ํ๋ค.
๋ ธ๋์์ ๋ฒํผ๋ฅผ ์ง์ ๋ค๋ฃฐ ์ ์๋ ํด๋์ค๊ฐ ์๋ค.
const buffer = Buffer.from('์ ๋ฅผ ๋ฒํผ๋ก ๋ฐ๊ฟ๋ณด์ธ์');
console.log('from():', buffer);
console.log('length:', buffer.length);
console.log('toString():', buffer.toString());
const array = [Buffer.from('๋์ '), Buffer.from('๋์ '), Buffer.from('๋์ด์ฐ๊ธฐ')];
const buffer2 = Buffer.concat(array);
console.log('concat():', buffer2.toString());
const buffer3 = Buffer.alloc(5);
console.log('alloc():', buffer3);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
from(): <Buffer ec a0 ...>
legnth: 32
toString(): ์ ๋ฅผ ๋ฒํผ๋ก ๋ฐ๊ฟ๋ณด์ธ์.
concat(): ๋์ ๋์ ๋์ด์ฐ๊ธฐ
alloc(): <Buffer 00 ..>
Buffer ๊ฐ์ฒด๋ ์ฌ๋ฌ๊ฐ์ง ๋ฉ์๋๋ฅผ ์ ๊ณต
- from(๋ฌธ์์ด): ๋ฌธ์์ด์ ๋ฒํผ๋ก ๋ฐ๊ฟ ์ ์์. length ์์ฑ์ ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์๋ฆฌ๋ ๋ฐ์ดํธ ๋จ์
- toString(๋ฒํผ): ๋ค์ ๋ฌธ์์ด๋ก ๋ฐ๊ฟ์ค๋ค. ์ด๋ ์ธ์ฝ๋ฉ๋ ๊ฐ๋ฅํ๋ค.
- concat(๋ฐฐ์ด): ๋ฐฐ์ด์ ํ๋๋ก ํฉ์น๋ค.
- alloc(๋ฐ์ดํธ): ๋น ๋ฒํผ๋ฅผ ์์ฑ ๋ฐ์ดํธ๋ฅผ ์ธ์๋ก ๋ฃ์ผ๋ฉด ํด๋น ํฌ๊ธฐ์ ๋ฒํผ๊ฐ ์์ฑ. ๋ฐ์ดํธ๋ฅผ ์ธ์๋ก ๋ฃ์ผ๋ฉด ํด๋น ํฌ๊ธฐ์ ๋ฒํผ๊ฐ ์์ฑ๋๋ค.
readFile ๋ฐฉ์์ ๋ฒํผ๊ฐ ํธ๋ฆฌํ๊ธฐ๋ ํ์ง๋ง ๋ฌธ์ ์ ๋ ์๋ค. ๋ง์ฝ ์ฉ๋์ด 100MB์ธ ํ์ผ์ด ์์ผ๋ฉด ์ฝ์ ๋ ๋ฉ๋ชจ๋ฆฌ์ 100MB์ ๋ฒํผ๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ์ด ์์ ์ ๋์์ ์ด๊ฐ๋งํด๋ 1GB์ ๋ฌํ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฌ์ฉ๋๋ค. ์ด ์์ ์ ๋์์ 10๊ฐ๋ง ํด๋ .. ํฐ์ง.
๊ฒ๋ค๋ผ ์ฝ๊ธฐ, ์์ถ, ํ์ผ์ฐ๊ธฐ ๋ฑ์ ์กฐ์์ ์ฐ๋ฌ์ ํ ๋ ๋งค๋ฒ ์ ์ฒด ์ฉ๋์ ๋ฒํผ๋ก ์ฒ๋ฆฌํด์ผ ํ๋ฏ๋ก ๋งค๋ฒ ์ ์ฒด ์ฉ๋์ ๋ฒํผ๋ฅผ ๋ค ์จ์ผํจ.
์ด๊ฑธ ํด๊ฒฐํ๊ณ ์ ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์๊ฒ ๋ง๋ค๊ณ ๋๋ ๋ณด๋ด๋ ๋ฐฉ์์ด ๋ฑ์ฅ ์ด๊ฒ์ด ๋ฐ๋ก ์คํธ๋ฆผ
ํ์ผ ์ฝ๋ ๋ฉ์๋๋ก๋ createReadStream์ด ์์
// readme3.txt
์ ๋ ์กฐ๊ธ์ฉ ๋๋ ์ ์ ๋ฌ๋ฉ๋๋ค. ๋๋ ์ง ์กฐ๊ฐ์ chunk๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
// createReadStream.js
const fs = require('fs');
const readStream = fs.createReadStream('./readme3.txt', { highWaterMark: 16 });
const data = [];
readStream.on('data', (chunk) => {
data.push(chunk);
console.log('data :', chunk, chunk.length);
});
readStream.on('end', () => {
console.log('end :', Buffer.concat(data).toString());
});
readStream.on('error', (err) => {
console.log('error :', err);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
<Buffer ec a0 80 ...> 16
<Buffer ec a0 80 ...> 16
<Buffer ec a0 80 ...> 16
<Buffer ec a0 80 ...> 16
<Buffer ec a0 80 ...> 16
<Buffer ec a0 80 ...> 16
์ ๋ ์กฐ๊ธ์ฉ ๋๋ ์ ์ ๋ฌ๋ฉ๋๋ค. ๋๋ ์ง ์กฐ๊ฐ์ chunk๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
๋จผ์ createReadStream์ผ๋ก ์ฝ๊ธฐ ์คํธ๋ฆผ์ ๋ง๋ ๋ค. ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ฝ์ ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋ฃ๋๋ค.
๋๋ฒ์จฐ ์ธ์๋ ์ต์ ๊ฐ์ฒด์ธ๋ฐ, hughWaterMark๋ผ๋ ์ต์ ์ด ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์ ํ ์ ์๋ ์ต์ ์ด๋ค.
readStream์ ๋ณดํต data, error, end๋ฅผ ์ฌ์ฉํ๋ค. ๊ฐ ์คํธ๋ฆผ์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ถ์ฌ์ ์ฌ์ฉํ๋ค.
์ด๋ฒ์๋ ์จ๋ณด์
const fs = require('fs');
const writeStream = fs.createWriteStream('./writeme2.txt');
writeStream.on('finish', () => {
console.log('ํ์ผ ์ฐ๊ธฐ ์๋ฃ');
});
writeStream.write('์ด ๊ธ์ ์๋๋ค.\n');
writeStream.write('ํ ๋ฒ ๋ ์๋๋ค.');
writeStream.end();
์ฐ๋๊ฒ๋ ๋ฎ์๋ค
์ด๋ฒ์๋ ์ฝ๊ณ ๊ทธ ์คํธ๋ฆผ์ ์ ๋ฌ๋ฐ์ ๋ค๋ฅธ๋ฐ์ ์จ๋ณด์.
๋ญ ํ์ผ ๋ณต์ฌ ๊ธฐ๋ฅ์ธ๋ฐ ์คํธ๋ฆผ๋ผ๋ฆฌ ์ฐ๊ฒฐํ๋ ๊ฒ์ 'ํ์ดํํ๋ค'๋ผ๊ณ ํํํ๋ค. ์ก์ฒด๊ฐ ๊ด์ ๋ฐ๋ผ ํ๋ฅธ๋ค๊ณ ํด์ ์ง์ด์ง ์ด๋ฆ์ด๋ค.
const fs = require('fs');
const readStream = fs.createReadStream('readme4.txt');
const writeStream = fs.createWriteStream('writeme3.txt');
readStream.pipe(writeStream);
๊ฒฐ๊ณผ๋ ๋ญ ์๊ฒ ์ง?
๋ค์ ์ฝ๋๋ ํ์ผ์ ์ฝ์ ํ gzip ๋ฐฉ์์ผ๋ก ์์ถํ๋ ์ฝ๋
const zlib = require('zlib');
const fs = require('fs');
const readStream = fs.createReadStream('./readme4.txt');
const zlibStream = zlib.createGzip();
const writeStream = fs.createWriteStream('./readme4.txt.gz');
readStream.pipe(zlibStream).pipe(writeStream);
์คํธ๋ฆผ ๋ชจ๋์ pipeline ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ์ฌ๋ฌ๊ฐ์ ํ์ดํ๋ฅผ ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ๋ ์๋ค.
import { pipeline } from 'stream/promises';
import zlib from 'zlib';
import fs from 'fs';
await pipeline(
fs.createReadStream('./readme4.txt'),
zlib.createGZip(),
fs.createWriteStream('./readme4.txt'),
)
ํ์ดํ๋ผ์ธ ์ฌ์ฉํ๋ฉด ์ข์ ์ ์ด ์ค๊ฐ์ AbortController๋ฅผ ์ฌ์ฉํด ์ํ ๋ ํ์ดํ๋ฅผ ์ค๋จํ ์ ์์.
import { pipeline } from 'stream/promises';
import zlib from 'zlib';
import fs from 'fs';
const ac = new AbortController();
const signal = ac.signal;
setTimeout(() => ac.abort(), 1); // 1ms ๋ค์ ์ค๋จ
await pipeline(
fs.createReadStream('./readme4.txt'),
zlib.createGZip(),
fs.createWriteStream('./readme4.txt'),
{ signal },
);
์ํ๋ ์์ ์ abort ํธ์ถํ๋ฉด ์ค๋จ๋๋ค.
์๋๋ 1๊ธฐ๊ฐ ํ์ผ ์์ฑํ๋ ์ฝ๋
const fs = require('fs');
const file = fs.createWriteStream('./big.txt');
for (let i =0;, i <= 100000000; i++) {
file.write('์์ฒญ๋๊ฒ ํฐ ํ์ผ ์
๋ก๋');
}
file.end()
big.txt๋ฅผ big2.txt๋ก ๋ณต์ฌํด๋ณด์.
const fs = require('fs');
console.log('before: ', process.memoryUsage().rss);
const data1 = fs.readFileSync('./big.txt');
fs.writeFileSync('./big2.txt', data1);
console.log('buffer: ', process.memoryUsage().rss);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
before: 18137088 // ์ฝ 18MB
buffer: 1018133952 // 1GB์ด์
๋ฉ๋ชจ๋ฆฌ์ ํ์ผ์ ๋ชจ๋ ์ฌ๋ ค๋ ํ writeFileSync๋ฅผ ์ํํ์.
์ด์ ๋ ์คํธ๋ฆผ์ ์ฌ์ฉํด ํ์ผ big3.txt๋ก ๋ณต์ฌํด๋ณด์.
const fs = require('fs');
console.log('before: ', process.memoryUsage().rss);
const readStream = fs.createReadStream('./big.txt');
const writeStream = fs.createWriteStream('./big3.txt');
readStream.pipe(writeStream);
readStream.on('end', () => {
console.log('stream: ', process.memoryUsage().rss);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
before: 18087936
stream: 62472192
# ๊ธฐํ fs ๋ฉ์๋ ์์๋ณด๊ธฐ
์ง๊ธ๊น์ง๋ ๋จ์ ํ์ผ์ด์๋ค๋ฉด ์ด์ ๋ ํด๋๋ ์ปจํธ๋กค ํด๋ณด์
const fs = require('fs').promises;
const constants = require('fs').constants;
// F_OK, W_OD, R_OK ํ์ผ ์กด์ฌ์ฌ๋ถ, ์ฝ๊ธฐ ๊ถํ ์ฌ๋ถ, ์ฐ๊ธฐ ๊ถํ ์ฌ๋ถ
fs.access('./folder', constants.F_OK | constants.W_OK | constants.R_OK)
.then(() => {
return Promise.reject('์ด๋ฏธ ํด๋ ์์');
})
.catch((err) => {
if (err.code === 'ENOENT') { // ํ์ผ/ํด๋๊ฐ ์์๋์ ์๋ฌ์ฝ๋
console.log('ํด๋ ์์');
return fs.mkdir('./folder'); // ํด๋๋ฅผ ๋ง๋๋ ๋ฉ์๋ -> ์ด๋ฏธ ํ์ผ์ด ์๋ค๋ฉด ์๋ฌ
}
return Promise.reject(err);
})
.then(() => {
console.log('ํด๋ ๋ง๋ค๊ธฐ ์ฑ๊ณต');
return fs.open('./folder/file.js', 'w'); // ํ์ผ ๊ฐ์ ธ์ค๊ธฐ, ํ์ผ ์๋ค๋ฉด ์๋ก ๋ง๋ฆ
// w์ฐ๊ธฐ r์ฝ๊ธฐ a์ถ๊ฐ
})
.then((fd) => {
console.log('๋น ํ์ผ ๋ง๋ค๊ธฐ ์ฑ๊ณต', fd);
return fs.rename('./folder/file.js', './folder/newfile.js'); // ํ์ผ ์ด๋ฆ ๋ฐ๊ฟ
// ๊ธฐ์กด ํ์ผ์ ์์น์ ์๋ก์ด ํ์ผ์ ์์น ์ ๊ธฐ, ๊ผญ ๊ฐ์ ํด๋๋ฅผ ์ง์ ํ ํ์ ์์ด์ ์๋ผ๋ด๊ธฐ ๊ฐ์ ๊ธฐ๋ฅ ๊ฐ๋ฅ
})
.then(() => {
console.log('์ด๋ฆ ๋ฐ๊พธ๊ธฐ ์ฑ๊ณต');
})
.catch((err) => {
console.error(err);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
$node fsCreate
ํด๋ ์์
ํด๋ ๋ง๋ค๊ธฐ ์ฑ๊ณต
๋น ํ์ผ ๋ง๋ค๊ธฐ ์ฑ๊ณต
์ด๋ฆ ๋ฐ๊พธ๊ธฐ ์ฑ๊ณต
$node fsCreate
์ด๋ฏธ ํด๋ ์์
์ด๋ฒ์๋ ๋ด์ฉ ํ์ธ์ด๋ ์ญ์ ๊ฐ์ ๋ฉ์๋ ์์๋ณด๊ธฐ
const fs = require('fs');
fs.readdir('./folder', (err, dir) => {
if (err) {
throw err;
}
console.log('ํด๋ ๋ด์ฉ ํ์ธ', dir);
fs.unlink('./folder/newfile.js', (err) => {
if (err) {
throw err;
}
console.log('ํ์ผ ์ญ์ ์ฑ๊ณต');
fs.rmdir('./folder', (err) => {
if (err) {
throw err;
}
console.log('ํด๋ ์ญ์ ์ฑ๊ณต');
});
});
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
ํด๋ ๋ด์ฉ ํ์ธ[ 'newfile.js' ]
ํ์ผ ์ญ์ ์ฑ๊ณต
ํด๋ ์ญ์ ์ฑ๊ณต
readdir์ ํด๋ ์์ ๋ด์ฉ๋ฌผ์ ํ์ธํ ์ ์๋ค. ๋ฐฐ์ด ์์ ๋ด๋ถ ํ์ผ๊ณผ ํด๋๋ช ์ด ๋์จ๋ค.
์์ด์ง ํ์ผ ํ๋ฒ ๋ ์ง์ฐ๋ฉด ENOENT์๋ฌ ๋ฐ์
createReadStream๊ณผ createWriteStream์ pipeํ์ง ์์๋ ํ์ผ์ ๋ณต์ฌํ ์ ์๋ค.
const fs = require('fs');
fs.copyFile('readme4.txt', 'writeme4.txt')
.then(() => {
console.log('๋ณต์ฌ ์๋ฃ');
})
.catch((error) => {
console.error(error);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
๋ณต์ฌ์๋ฃ
read4me์ ๋ด์ฉ์ด writeme4๋ก ์์ ํ ๋ณต์ฌ๋๋ค.
๋ง์ง๋ง์ผ๋ก ํ์ผ/ํด๋ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์ํ ์ ์๋ watch ๋ฉ์๋์ ๋ํด์ ์์๋ณด์
const fs = require('fs');
fs.watch('./target.txt', (eventType, filename) => {
console.log(eventType, filename);
});
//์ถ๋ ฅ๊ฒฐ๊ณผ
// ๋ด์ฉ๋ฌผ ์์ ํ
change target.txt
change target.txt
// ํ์ผ๋ช
๋ณ๊ฒฝ ๋๋ ํ์ผ ์ญ์ ํ
rename target.txt
change์ด๋ฒคํธ๊ฐ 2๋ฒ ๋ฐ์ํ๋ ์ค๋ฌด์์ ์ฃผ์
rename ์ดํ์๋ ์ด๋ฆ์ด ๋ฌ๋ผ์ ธ์ ๋์ด์ watch๋ก ํธ๋ํนํ ์ ์์ผ๋ ์ฃผ์
# ์ค๋ ๋ ํ ์์๋ณด๊ธฐ
fs ๋ชจ๋์ ๋น๋๊ธฐ ๋ฉ์๋๋ค์ ์ฌ์ฉํด ๋ดค์.
๋น๋๊ธฐ ๋ฉ์๋๋ค์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋๊ณ ์คํ๋ ํ์๋ ๋ค์ ๋ฉ์ธ ์ค๋ ๋์ ์ฝ๋ฐฑํจ์๋ ํ๋ก๋ฏ์ค์ then ๋ถ๋ถ์ด ์คํ๋๋ค. ์ด๋ fs๋ฉ์๋๋ฅผ ์ฌ๋ฌ๋ฒ ์คํํด๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋์์ ์ฒ๋ฆฌ๋๋๋ฐ ๊ทธ ์ด์ ๋ ์ค๋ ๋ ํ์ด ์๊ธฐ ๋๋ฌธ
const crypto = require('crypto');
const pass = 'pass';
const salt = 'salt';
const start = Date.now();
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('1:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('2:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('3:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('4:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('5:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('6:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('7:', Date.now() - start);
});
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
console.log('8:', Date.now() - start);
});
// ์ถ๋ ฅ๊ฒฐ๊ณผ
4: 1548
2: 1583
1: 1590
3: 1695
6: 3326
5: 3463
7: 3659
8: 3682
์ค๋ ๋ ํ์ด ๋์์ ์ฒ๋ฆฌํด์ ๋ญ๊ฐ ๋จผ์ ์คํ๋ ์ง ๋ชจ๋ฆ
๋ค๋ง ํ๋์ ๊ท์น์ ๋ฐ๊ฒฌํ ์๋ ์๋๋ฐ 5-8๊ทธ๋ฃน์ด ๋ฌถ์ฌ์๊ณ 1-4๊ทธ๋ฃน๋ ๋ฌถ์ฌ์์. ๊ทธ๋ฆฌ๊ณ ์๊ฐ๋ ๋ ์์๋๋ค.
์๋ํ๋ฉด ๊ธฐ๋ณธ์ ์ธ ์ค๋ ๋์ ๊ฐฏ์๊ฐ 4๊ฐ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ์ฒ์ 4๊ฐ์ ์์ ์ด ๋์์ ์คํ๋๊ณ , ๊ทธ๊ฒ๋ค์ด ์ข ๋ฃ๋๋ฉด 4๊ฐ ๋ ์คํ๋๋ค.
์ฝ์ด๊ฐ ๋ง์ฝ PC์ ๋ ๋ง๋ค๋ง ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๊ฐ๋ฅํ๋ค.
# ์ด๋ฒคํธ ์์๋ณด๊ธฐ
์คํธ๋ฆผ์ ๋ฐฐ์ธ๋ ์ฐ๋ฆฌ๋ on('data', ์ฝ๋ฐฑ), end('data', ์ฝ๋ฐฑ)์ ์ฌ์ฉํ๋ค. ๋ฐ๋ก data๋ผ๋ ์ด๋ฒคํธ๊ฐ end๋ผ๋ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ๋๋ก ๋ฑ๋กํ ๊ฒ
createReadStream ๊ฐ์ ๊ฒฝ์ฐ ๋ด๋ถ์ ์ผ๋ก ์์์ data์ end ์ด๋ฒคํธ๋ฅผ ํธ์ถํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ์ง์ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์๋ ์์.
const EventEmitter = require('events');
const myEvent = new EventEmitter();
myEvent.addListener('event1', () => {
console.log('์ด๋ฒคํธ 1');
});
myEvent.on('event2', () => {
console.log('์ด๋ฒคํธ 2');
});
myEvent.on('event2', () => {
console.log('์ด๋ฒคํธ 2 ์ถ๊ฐ');
});
myEvent.once('event3', () => {
console.log('์ด๋ฒคํธ 3');
}); // ํ ๋ฒ๋ง ์คํ๋จ
myEvent.emit('event1'); // ์ด๋ฒคํธ ํธ์ถ
myEvent.emit('event2'); // ์ด๋ฒคํธ ํธ์ถ
myEvent.emit('event3');
myEvent.emit('event3'); // ์คํ ์ ๋จ
myEvent.on('event4', () => {
console.log('์ด๋ฒคํธ 4');
});
myEvent.removeAllListeners('event4');
myEvent.emit('event4'); // ์คํ ์ ๋จ
const listener = () => {
console.log('์ด๋ฒคํธ 5');
};
myEvent.on('event5', listener);
myEvent.removeListener('event5', listener);
myEvent.emit('event5'); // ์คํ ์ ๋จ
console.log(myEvent.listenerCount('event2'));
์ด๋ฒคํธ ๋ง๋๋ ค๋ฉด myEvent ๊ฐ์ฒด๋ฅผ ๋จผ์ ๋ง๋ค์ด์ผ ํจ.
๊ทธ๋ฅ ์ฝ๋ ์ฝ๋ค๋ณด๋ฉด ๊ฐ์ด ์จ๋ค.
์ ์ง๊ธ๊น์ง ๋ฐฐ์ด ๊ฒ๋ง์ผ๋ก๋ ์ด๋ฒคํธ ์ฒ๋ฆฌํ๊ธฐ์ ์ถฉ๋ถํ๋ค
์ด์ ๋ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์
# ์์ธ ์ฒ๋ฆฌํ๊ธฐ
๋ ธ๋์์๋ ์์ธ์ฒ๋ฆฌ ์ค์ํจ. ์์ธ ์ฒ๋ฆฌ ๋ชปํ๋ฉด ๋ ธ๋ ํ๋ก์ธ์ค๋ฅผ ๋ฉ์ถ๊ฒ ํ ์๋ ์์.
๋ ธ๋๋ ์ค๋ ๋ ํ๋ ๋ฟ์ด๋ผ ๊ทธ๊ฑฐ ์ ๊ด๋ฆฌํด์ผํจ. ์๋ชปํ๋ฉด ์ ์ฒด ๋ฉ์ถค
์๋ฌ ๋ก๊ทธ๊ฐ ๊ธฐ๋ก๋๋๋ผ๋ ํ๋ก๊ทธ๋จ์ ๋์๊ฐ์ผ ํจ.
๋ฌธ๋ฒ์์ ์๋ฌ๋ ์๋ค๊ณ ๊ฐ์ ํ๊ฒ ์. ์ค์ ๋ฐฐํฌ์์ ๊ทธ๊ฑฐ ์๋๊ฑด ํฐ์ผ๋จ. ์ข์ ์๋ํฐ๋ก ๋ฌธ๋ฒ ๊ฒ์ฌ ํด์ ์ฌ์ฉํด๋ณด์.
์๋ฌ๊ฐ ๋ฐ์ํ ๋ถ๋ถ์ try - catch๋ก ๊ฐ์ผ๋ค.
setInterval(() => {
console.log('์์');
try {
throw new Error('์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!');
} catch (err) {
console.error(err);
}
}, 1000);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
์์
Error: ์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!
...
์์
Error: ์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!
...
๋ฌดํ๋ฐ๋ณต
setInterval์ ํ ์ด์ ๋ ์๋ฒ๊ฐ ๋ฉ์ท๋์ง ์ฌ๋ถ๋ฅผ ์ฒดํฌํ๊ธฐ ์ํด
ํ๋ก์ธ์ค ๊ด๋ จ ์๋ฌ๋ก ๋ฉ์ถ๋ฉด ํด๋น ๋ฉ์๋๋ ๋ฉ์ถ ๊ฒ์ ํด๋น ์ฝ๋๋ ์๋ฌ๋ฅผ throw์์ ๊ฐ์ ๋ก ๋์ง๊ณ ์์.
์ด๋ฒ์๋ ๋ ธ๋ ์์ฒด์์ ์๋ฌ ์ก์์ฃผ๋ ์ฝ๋ ์์๋ณด์.
const fs = require('fs');
setInterval(() => {
fs.unlink('./abcdefg.js', (err) => {
if (err) {
console.error(err);
}
});
}, 1000);
์ด๋ฒ์๋ unlink๋ก ์กด์ฌํ์ง ์๋ ํ์ผ์ ์ง์ฐ๊ณ ์๋ค. ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ง ๋คํํ ๋ ธ๋ ๋ด์ฅ ๋ชจ๋์ ์๋ฌ๋ ์คํ์ค์ธ ํ๋ก์ธ์ค๋ฅผ ๋ฉ์ถ์ง ์๋๋ค. ์๋ฌ๋ก๊ทธ๋ฅผ ๊ธฐ๋กํด๋๊ณ ๋์ค์ ์์ธ์ ์ฐพ์ ์ฎ์ดํ๋ฉด ๋๋ค.
throwํ๋ ๊ฒฝ์ฐ์๋ ๋ฐ๋์ try/catch๋ฌธ์ผ๋ก ์๋ฌ๋ฅผ ์ก์์ผ ํ๋ค.
๋ ธ๋ 16๋ถํฐ๋ promise์ ์๋ฌ๋ ๋ฐ๋์ ์บ์นํด์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ข ๋ฃ๋๋ค.
process.on('uncaughtException', (err) => {
console.error('์๊ธฐ์น ๋ชปํ ์๋ฌ', err);
});
setInterval(() => {
throw new Error('์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!');
}, 1000);
setTimeout(() => {
console.log('์คํ๋ฉ๋๋ค');
}, 2000);
// ์ถ๋ ฅ๊ฒฐ๊ณผ
์๊ธฐ์น ๋ชปํ Error: ์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!
...
์คํํฉ๋๋ค.
์๊ธฐ์น ๋ชปํ Error: ์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!
์๊ธฐ์น ๋ชปํ Error: ์๋ฒ๋ฅผ ๊ณ ์ฅ๋ด์ฃผ๋ง!
// ๊ณ์ ๋ฐ๋ณต
์ ์ฝ๋๋ ์ ๋ง ์์ธก ๋ถ๊ฐ๋ฅํ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๋ ์์ ์ด๋ค.
process ๊ฐ์ฒด์ uncauthtException ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ฌ์๋ค. ์ฒ๋ฆฌํ์ง ๋ชปํ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์คํ๋๊ณ ํ๋ก์ธ์ค๊ฐ ์ ์ง๋๋ค. ์คํ ํ 1์ด๋ง์ setInterval์์ ์๋ฌ๊ฐ ๋ฐ์ํด ํ๋ก์ธ์ค๊ฐ ๋ฉ์ถ๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง uncauhtException ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์ฐ๊ฒฐ๋์ด ์์ผ๋ฏ๋ก ํ๋ก์ธ์ค๊ฐ ๋ฉ์ถ์ง ์๋๋ค.
uncaughtException์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ์ด๋ ๊ณ์ ์ฑํผ๋๋ค.
ํ์ง๋ง ์ด ์ฝ๋๋ ์ตํ์ ์๋จ์ผ๋ก ์ฌ์ฉํ๋ผ๊ณ ๊ถ์ฅํ๋ค.
uncaughtException ์ด๋ฒคํธ ๋ฐ์ ํ ๋ค์ ๋์์ด ์ ๋๋ก ๋์ํ๋์ง๋ฅผ ๋ณด์ฆํ์ง ์๋๋ค.
๋ฐ๋ผ์ ์๋ ์๋ฌ ๋ด์ฉ์ ๊ธฐ๋กํ๋ ์ ๋๋ก ์ฌ์ฉํ ํ process.exit()์ผ๋ก ์ข ๋ฃํ๋๊ฒ ์ข์.
์๋ฒ๋ ์๋ฌ์์ ์ธ์.
์๋ฌ๊ฐ ๋ฐ์ํ ๋ ์๋ฌ๋ฅผ ์ฒ ์ ํ ๋ก๊น ํ๋ ์ต๊ด์ ๊ฐ์
'๐ฐ๏ธ Node.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Node.js] #6 ์ต์คํ๋ ์ค ์น ์๋ฒ ๋ง๋ค๊ธฐ (0) | 2023.07.23 |
---|---|
[Node.js] #5 ํจํค์ง ๋งค๋์ (0) | 2023.07.23 |
[Node.js] #4 http ๋ชจ๋๋ก ์๋ฒ ๋ง๋ค๊ธฐ (0) | 2023.07.22 |
[Node.js] #2 ์์๋ฌ์ผ ํ ์๋ฐ์คํฌ๋ฆฝํธ (0) | 2023.07.17 |
[Node.js] #1 ํต์ฌ๊ฐ๋ ์ดํดํ๊ธฐ (0) | 2023.07.16 |