Notice
Recent Posts
Recent Comments
Link
ยซ   2024/05   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
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
Archives
Today
Total
๊ด€๋ฆฌ ๋ฉ”๋‰ด

lgvv98

[Node.js] #3 ๋…ธ๋“œ ๊ธฐ๋Šฅ ์•Œ์•„๋ณด๊ธฐ ๋ณธ๋ฌธ

๐Ÿ›ฐ๏ธ Node.js

[Node.js] #3 ๋…ธ๋“œ ๊ธฐ๋Šฅ ์•Œ์•„๋ณด๊ธฐ

๐Ÿฅ• ์บ๋Ÿฟ๋งจ 2023. 7. 22. 01:35

#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()์œผ๋กœ ์ข…๋ฃŒํ•˜๋Š”๊ฒŒ ์ข‹์Œ.

 

์„œ๋ฒ„๋Š” ์—๋Ÿฌ์™€์˜ ์‹ธ์›€.

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์—๋Ÿฌ๋ฅผ ์ฒ ์ €ํžˆ ๋กœ๊น…ํ•˜๋Š” ์Šต๊ด€์„ ๊ฐ–์ž

Comments