[week_06] Node.js ๊ธฐ์ดˆ | Node.js์˜ ์ดํ•ด, ํŠน์ง•, ES6, ๋น„๋™๊ธฐ ์ฝ”๋”ฉ, ์ด๋ฒคํŠธ ๋ฃจํ”„
elice/WIL

[week_06] Node.js ๊ธฐ์ดˆ | Node.js์˜ ์ดํ•ด, ํŠน์ง•, ES6, ๋น„๋™๊ธฐ ์ฝ”๋”ฉ, ์ด๋ฒคํŠธ ๋ฃจํ”„

1. Node.js๋ž€

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์–ด๋А ํ™˜๊ฒฝ์—์„œ๋‚˜ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์‹คํ–‰๊ธฐ

  • Browser์˜ JavaScript
    • ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰
    • ์›น ๋‚ด๋ถ€์˜ ์ œํ•œ๋œ ๋™์ž‘
    • ์›น ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์ž์˜ ์–ธ์–ด
  • Node.js
    • ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์‹คํ–‰ (์–ด๋А ํ™˜๊ฒฝ์—์„œ๋“  ์‹คํ–‰ ๊ฐ€๋Šฅ)
    • ์ œํ•œ ์—†๋Š” ๋™์ž‘
    • ๋‹ค์–‘ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ

 

2. Node.js์˜ ํŠน์ง•

์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ - ๋น„๋™๊ธฐ - ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜

2-1. ์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ

  • ์“ฐ๋ ˆ๋“œ(Thread): ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๋‹จ์œ„, ํ•œ ๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๋Š” ํ•œ ๋ฒˆ์— ํ•œ ๊ฐ€์ง€ ๋™์ž‘๋งŒ ์‹คํ–‰ ๊ฐ€๋Šฅ
  • ์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ: ํ•œ ๋ฒˆ์— ํ•œ ๊ฐ€์ง€ ๋™์ž‘๋งŒ ์ˆ˜ํ–‰ํ•จ
  • ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ: ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋™์ž‘ ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ
  • ์žฅ์ 
    • ์“ฐ๋ ˆ๋“œ ์ƒ์„ฑ ๋น„์šฉ์ด ์—†๋‹ค
    • ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋Š˜์–ด๋‚˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— CPU ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ์— ํšจ์œจ์ 
  • ๋‹จ์ 
    • ์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜์˜ ์ž‘์—…๋“ค์˜ ํšจ์œจ์ด ๋–จ์–ด์ง ex) CPU ์—ฐ์‚ฐ ์ž‘์—…

๐Ÿ‘‰ ๊ทธ๋ž˜์„œ Node.js๋Š” ๋น„๋™๊ธฐ ๋™์ž‘์œผ๋กœ ์“ฐ๋ ˆ๋“œ ๊ธฐ๋ฐ˜์˜ ์ž‘์—…์„ ์ตœ์†Œํ™” ํ•œ๋‹ค.

2-2. ๋น„๋™๊ธฐ

  • ๋™์ž‘์„ ์‹คํ–‰ํ•œ ํ›„ ์™„๋ฃŒ๊ฐ€ ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๋Š” ๋ฐฉ์‹
  • ๋™์ž‘์˜ ์™„๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ๋™์ž‘์„ ๋ฐ”๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅ
  • Node.js๋Š” ์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ์ด๊ธฐ ๋–„๋ฌธ์— ๋น„๋™๊ธฐ ๋ฐฉ์‹์„ ์‚ฌ์šฉ

2-3. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜

  • ๋น„๋™๊ธฐ ๋™์ž‘์˜ ์™„๋ฃŒ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ๋น„๋™๊ธฐ ๋ฐฉ์‹์€ ํŠน์ • ๋™์ž‘์„ ์‹คํ–‰ํ•œ ํ›„, ํ•ด๋‹น ๋™์ž‘์„ ์ „ํ˜€ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์Œ
  • ๋Œ€์‹  ํ•ด๋‹น ๋™์ž‘์ด ์™„๋ฃŒ๋  ๊ฒฝ์šฐ ์‹คํ–‰ํ•  ํ•จ์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ๋“ฑ๋กํ•จ (= ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.)
  • ๋น„๋™๊ธฐ ๋™์ž‘์ด ์™„๋ฃŒ๊ฐ€ ๋˜๋ฉด ๋ฏธ๋ฆฌ ๋“ฑ๋ก๋œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰
โœจ ๊ฒฐ๋ก 
Node.js๋Š” ์‹ฑ๊ธ€ ์“ฐ๋ ˆ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋น„๋™๊ธฐ ๋™์ž‘์ด ํ•„์š”ํ•˜๊ณ ,
๋น„๋™๊ธฐ ๋™์ž‘์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

3. Node.js ์‹œ์ž‘ํ•˜๊ธฐ

  • Node.js๋Š” ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœ์ค‘์ธ ๊ธฐ์ˆ 
    • ์ƒˆ๋กœ์šด ๋ฒ„์ „์—์„œ๋Š” ๋ณด์•ˆ ์ด์Šˆ ๋ฐ ๋ฒ„๊ทธ ์ˆ˜์ •, ์ตœ์‹ ๊ธฐ์ˆ ๋“ค์ด ๋น ๋ฅด๊ฒŒ ์ ์šฉ๋˜๊ณ  ์žˆ๋‹ค.
    • ๊ธ‰๋ณ€ํ•˜๋Š” ๊ธฐ์ˆ ์€ ๊ฐ€์žฅ ์•ˆ์ •์ ์ธ ์ตœ์‹  ๋ฒ„์ „์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ตœ์„ 
  • LTS
    • Long-Term Support ๋ฒ„์ „
    • Node.js์˜ ์•ˆ์ •์ ์ด๊ณ , ์˜ค๋ž˜ ์ง€์›๋˜๋Š” ๋ฒ„์ „

 

4. ES6

  • ECMAScript
    • ๊ณ„์†ํ•ด์„œ ๋ฐœ์ „ํ•ด๊ฐ€๋Š” JavaScript์˜ ํ‘œ์ค€ ๋ฌธ๋ฒ•
    • 2015๋…„, ECMAScript ๋ฒ„์ „ 6 ์ดํ›„๋กœ ๋งŽ์€ ํ˜„๋Œ€์ ์ธ ๋ฌธ๋ฒ•์ด ์ถ”๊ฐ€๋จ
    • ECMAScript ๋ฒ„์ „ 6 ์ดํ›„๋ฅผ ํ†ตํ‹€์–ด ์ผ๋ฐ˜์ ์œผ๋กœ ES6๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
  • ์‚ฌ์šฉ ์ด์œ 
    • ํ˜„๋Œ€์ ์ธ ๋ฌธ๋ฒ• โžก ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ
    • Node.js๋Š” ๋น ๋ฅด๊ฒŒ ์ตœ์‹  ECMAScript๋ฅผ ์ง€์›ํ•œ๋‹ค. (๋‹จ, ES6์˜ ๋ชจ๋“  ๋ฌธ๋ฒ•์„ ์ง€์›ํ•˜์ง€๋Š” ์•Š์Œ)

4-1. let, const

  • ๊ธฐ์กด์˜ var: ์ƒ์ˆ˜์™€ ๋ณ€์ˆ˜ ๊ตฌ๋ถ„์ด ์—†๋‹ค.
  • let๊ณผ const๋ฅผ ํ†ตํ•ด ์ƒ์ˆ˜์™€ ๋ณ€์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

4-2. Template String(``)

  • ๋ฐฑํ‹ฑ( ` )๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฌธ์ž๋ฅผ ํ‘œํ˜„
  • ${ }๋ฅผ ํ†ตํ•ด ๋ฌธ์ž์—ด ์‚ฌ์ด์— ๊ฐ„๋‹จํžˆ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

4-3. arrow function

// ๊ธฐ์กด
function doSomething(param) {
	console.log('do something');
}

// arrow function
const doSometing = (param) => { // ์ƒ์ˆ˜ํ˜•์œผ๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅ -> ์ƒˆ๋กœ ์„ ์–ธ ๋ถˆ๊ฐ€
	console.log('do something');
}

4-4. class

// ๊ธฐ์กด: prototype์œผ๋กœ class ํ•จ์ˆ˜ ๊ตฌํ˜„
function Model(name, age) {
	this.name = name;
    this.age = age;
}

Model.prototype.getInfo = function() {
	console.log(this.name, this.age);
}

// ES6 => ์ผ๋ฐ˜์ ์ธ ํ˜•ํƒœ์˜ class ๊ตฌํ˜„ ๊ฐ€๋Šฅ
class Model {
	constructor(name, age) {
    	this.name = name;
        this.age = age;
    }
    getInfo() {
    	console.log(this.name, this.age);
    }
}

4-5. destructing

// ๊ธฐ์กด ๋ฌธ๋ฒ•
var obj = {name: 'Tom', age: 5};
var name = obj.name;
var age = obj.age;

var arr = ['some', 'values'];
var first = arr[0];
var secont = arr[1];

// ES6
// Object์˜ key์™€ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋ณ€์ˆ˜ ์„ ์–ธ ๊ฐ€๋Šฅ
const obj = {name: 'Tom', age: 5};
const {name, age} = obj;
const {name: n1, age: a1} = obj;

const arr = ['some', 'values'];
// arr์—์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณ€์ˆ˜ ์„ ์–ธ ๊ฐ€๋Šฅ
const [first, second] = arr;
  • ๊ธฐ์กด
    • Object์™€ ๋ฐฐ์—ด์—์„œ ๊ฐ’์„ ๊บผ๋‚ด๊ธฐ ์œ„ํ•ด์„œ, ๊ฐ’์„ ํ•˜๋‚˜์”ฉ ์ง€์ •ํ•ด์„œ ๋ณ€์ˆ˜์— ์ €์žฅ
  • ES6
    • Object์—์„œ ๊ฐ’์„ ๊บผ๋‚ผ๋•Œ๋Š” ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ key์™€ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๊ฐ’์„ ๊บผ๋‚ด์™€์„œ ๋ณ€์ˆ˜ ์„ ์–ธ ๊ฐ€๋Šฅ
    • key์™€ ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๊ฐ’์„ ๊บผ๋‚ผ๋•Œ๋Š” { key ๊ฐ’: ๋ณ€์ˆ˜ ์ด๋ฆ„ } ์˜ ํ˜•ํƒœ ์‚ฌ์šฉ
    • ๋ฐฐ์—ด์—์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ๊บผ๋‚ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ์‹คํ–‰ ๊ฒฐ๊ณผ

 

5. ๋น„๋™๊ธฐ ์ฝ”๋”ฉ

  • Callback: ์ „ํ†ต์ ์ธ JavaScript์˜ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ฝ”๋”ฉ ๋ฐฉ์‹
  • Promise: callback์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•œ ๋น„๋™๊ธฐ ์ฝ”๋”ฉ ๋ฐฉ์‹
  • Async-Await: promise์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•œ ๋น„๋™๊ธฐ ์ฝ”๋”ฉ ๋ฐฉ์‹

5-1. Callback

db.getUsers((err, users) => {
	console.log(users);
});
  • getUsers์— ์ธ์ž๋กœ ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ getUsers๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋“ฑ๋ก๋˜๋Š” ์ด๋ฒคํŠธ ํ•จ์ˆ˜
  • ์ด๋ฒคํŠธ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๋Š” ํ˜•ํƒœ๋ฅผ Callback์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ์ฟผ๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š”์ง€, ํ˜น์€ ์œ ์ €๋ชฉ๋ก์˜ ๊ฒฐ๊ณผ๋กœ ๋ฏธ๋ฆฌ ๋“ฑ๋ก๋œ callback ํ•จ์ˆ˜ ์‹คํ–‰
  • callbackํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ์—๋Ÿฌ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด callback์˜ ํ‘œ์ค€
  • callback๋“ค์ด ๊ณ„์†ํ•ด์„œ ์—ฐ๊ฒฐ๋˜๋‹ค ๋ณด๋ฉด ์ฝœ๋ฐฑ ์ง€์˜ฅ ํ˜„์ƒ ๋ฐœ์ƒ

5-2. Promise

db.getUsersPromise()
	.then((uesrs) => {
    	return promise1(users);
    })
    .then(r1 => promise2(r1)
    .catch(~~);
  • then๊ณผ catch๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ์™€ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌ
  • Chaining์„ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ
  • Short-hand ํ‘œํ˜„ ๋ฐฉ๋ฒ•์œผ๋กœ ๋”์šฑ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ
    • Return ์ƒ๋žต ๊ฐ€๋Šฅ
    • ์ธ์ž๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ ( ) ์ƒ๋žต ๊ฐ€๋Šฅ
  • resolve, reject ๋‘ ๊ฐ€์ง€ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง
  • Promise.all(): promise ํ•จ์ˆ˜๋ฅผ ๋™์‹œ์— ์‹คํ–‰์‹œํ‚ค๊ณ  ๋“ฑ๋ก๋œ ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ๋งˆ๋ฌด๋ฆฌ๋˜๋ฉด ๊ฒฐ๊ณผ๊ฐ’์„ ํ•œ๊บผ๋ฒˆ์— ๋ฐ˜ํ™˜

5-3. Async-Await

async function doSomething() {
	const r1 = await promise1();
    const r2 = await promise2(r1);
    const r3 = await promise3(r1, r2);
    ...
    return r3;
}

doSomething().then(r3 => {console.log(r3)});
  • promise์˜ ๋‹ค๋ฅธ ๋ฌธ๋ฒ•
  • async ํ•จ์ˆ˜ ๋‚ด์—์„œ promise ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋Š” await์œผ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • awaitํ•œ promise ํ•จ์ˆ˜๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ ๊นŒ์ง€ ๋‹ค์Œ ๋ผ์ธ์œผ๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค.
  • async ํ•จ์ˆ˜์˜ return์€ Promise
  • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋Š” try-catch ๋ฌธ ํ™œ์šฉ

 

6. ์ด๋ฒคํŠธ ๋ฃจํ”„

  • ์ด๋ฒคํŠธ(event)๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ˜๋ณต๋˜๋Š” ๋™์ž‘(loop)
  • ์ฆ‰, Node.js๊ฐ€ ๋น„๋™๊ธฐ-์ด๋ฒคํŠธ ๋™์ž‘์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ผ๋ จ์˜ ๋ฐ˜๋ณต ๋™์ž‘
  • ๋น„๋™๊ธฐ ์ฝ”๋”ฉ์ด ์–ด๋–ค ์ˆœ์„œ๋กœ ์ˆ˜ํ–‰๋˜๋Š”์ง€์— ๋Œ€ํ•ด ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.
  • JavaScript์˜ ์ผ๋ฐ˜์ ์ธ ๋™์ž‘ ๋ฐฉ์‹
  • ๊ตฌ์„ฑ์š”์†Œ
    • Call Stack: ์ž‘์„ฑ๋œ ํ•จ์ˆ˜๋“ค์ด ๋“ฑ๋ก๋˜๋Š” LIFO ์Šคํƒ, ์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ์ฝœ์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๋•Œ๊นŒ์ง€ ์Šคํƒ์˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰
    • Message Queue: setTimeout๊ฐ™์€ ์ง€์—ฐ์‹คํ–‰ ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๋Š” FIFO ํ, ์ •ํ•ด์ง„ timing์ด ๋๋‚˜๊ณ  ์ฝœ์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๊ฒฝ์šฐ ๋“ฑ๋ก๋œ ํ•จ์ˆ˜๋ฅผ ์ฝœ์Šคํƒ์— ์ถ”๊ฐ€
    • Job Queue: Promise์— ๋“ฑ๋ก๋œ ์ฝœ๋ฐฑ์„ ๋“ฑ๋กํ•˜๋Š” FIFO ํ, ์ƒ์œ„ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „์— ์ฝœ์Šคํƒ์ด ๋น„์–ด์žˆ์ง€ ์•Š๋”๋ผ๋„ ์žกํ์— ๋“ฑ๋ก๋œ ์ฝœ๋ฐฑ์„ ์ฝœ์Šคํƒ์— ์ถ”๊ฐ€
  • ์ด๋ฒคํŠธ ๋ฃจํ”„์˜ ์ž์„ธํ•œ ๋™์ž‘ ๊ณผ์ •์€ ์—ฌ๊ธฐ์— ์ •๋ฆฌํ•ด๋‘์—ˆ๋‹ค.