KDT/TIL

8/24 TIL : node.js, promise, async/await

ebulsok 2022. 9. 7. 15:23

๐Ÿ”Ž node.js : Chrome V8 JavaScript ์—”์ง„์œผ๋กœ ๋นŒ๋“œ๋œ JavaScript ๋Ÿฐํƒ€์ž„

  • ์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด๋ผ ์–ด๋А ํ™˜๊ฒฝ์—์„œ๋„ ๋™์ž‘
  • ์„ฑ๋Šฅ์ด ๋น ๋ฅด๊ณ  ์ข‹์Œ
  • js๋ฅผ ์“ฐ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŽ์Œ
  • Ryan Dahl์ด ์„œ๋ฒ„์šฉ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœ

 

๐Ÿšฉ ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…(์œˆ๋„์šฐ ๊ธฐ์ค€)

  1. node.js ์„ค์น˜(https://nodejs.org/ko/)
  2. ๋ฒ„์ „ ๊ด€๋ฆฌ tool ์„ค์น˜(https://github.com/coreybutler/nvm-windows/releases)
  3. nvm ๋ฒ„์ „ ํ™•์ธ: [ํ„ฐ๋ฏธ๋„] nvm version
  4. node.js ๋ฒ„์ „ ํ™•์ธ: [ํ„ฐ๋ฏธ๋„] nvm ls

 

๐Ÿšฉ npm: node package manager

  • [ํ„ฐ๋ฏธ๋„] npm init -y
  • ํŒŒ์ผ ์‹คํ–‰: [ํ„ฐ๋ฏธ๋„] node ํŒŒ์ผ๋ช…

 

๐Ÿšฉ formatting: ์ฝ”๋“œ์˜ ์Šคํƒ€์ผ์„ ํ†ต์ผ์‹œ์ผœ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ณ  ๋ฒ„๊ทธ๋ฅผ ์˜ˆ๋ฐฉ

  1. prettier ์„ค์ •: [ํ„ฐ๋ฏธ๋„] npm install --save-dev prettier
  2. prettier ํ™•์žฅ ์„ค์น˜
  3. .prettierrc ํŒŒ์ผ ์ƒ์„ฑ
  4. { "semi": true, "singleQuote": true }
  5. .vscode ํด๋” ์ƒ์„ฑ, setting.json ํŒŒ์ผ ์ƒ์„ฑ
{
    "[javascript]": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode"
    }
}

 

๐Ÿšฉ Linting: formatting์— ๊ฐ€๊น์ง€๋งŒ ๋” ๋งŽ์€ ๊ทœ์•ฝ๊ณผ ๊ทœ์œจ์„ ๊ฒ€์‚ฌํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•, ์›น๊ฐœ๋ฐœ์—์„œ๋Š” airbnb์—์„œ ์‚ฌ์šฉํ•˜๋Š” linting ๊ทœ์œจ์ด ์œ ๋ช…ํ•จ

  1. ESLint ์„ค์น˜: [ํ„ฐ๋ฏธ๋„] npm install --save-dev eslint
  2. .eslintrc.js ํŒŒ์ผ ์ƒ์„ฑ
  3. module.exports = { extends: ['airbnb-base'], rules: { 'linebreak-style': 0, 'no-console': 'off', }, };
  4. airbnb linting rule: [ํ„ฐ๋ฏธ๋„] npm install --save-dev eslint-config-airbnb-base eslint-plugin-import

 

๐Ÿšฉ typescript ์„ค์น˜: [ํ„ฐ๋ฏธ๋„] npm install --save-dev typescript

  1. js ํŒŒ์ผ์— // @ts-check ์ฃผ์„ ์ถ”๊ฐ€
  2. [ํ„ฐ๋ฏธ๋„] npm install --save-dev @types/node

 

๐Ÿšฉ ๊ฐ„๋‹จํ•œ node.js ์„œ๋ฒ„ - main.js

// @ts-check
const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.end('Hello');
});

const PORT = 4000;
server.listen(PORT, () => {
  console.log(`The server is listening at port: ${PORT}`);
});

๐Ÿ”Ž JavaScript ์‹คํ–‰ ๊ฐœ๋…

  1. JS์˜ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋Š” ๋ช…๋ น์–ด๋ฅผ ์ˆœ์„œ๋Œ€๋กœ call stack์— ๋ฐ€์–ด ๋„ฃ๊ณ , ์Œ“์ธ ์ˆœ์„œ๋Œ€๋กœ ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•จ
  2. ๋ช…๋ น์–ด๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์™€์ค‘ web api ๋˜๋Š” callback queue์— ํ˜ธ์ถœ์ด ์ƒ๊ธฐ๋ฉด ํ•ด๋‹น ์˜์—ญ์œผ๋กœ ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์คŒ
  3. web api๋Š” ํ˜ธ์ถœ๋œ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌ ์™„๋ฃŒํ•˜๋ฉด callback queue์— ์™„๋ฃŒ๋œ ๊ฒƒ์„ ๋„ฃ์–ด์คŒ
  4. callback queue๋Š” call stack์ด ์ „๋ถ€ ๋น„๋ฉด, ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ callback queue์˜ ๊ฒƒ์„ call stack์— ๋ฐ€์–ด๋„ฃ์–ด์คŒ(tick)

 

๐Ÿšฉ callback

  • ์•„๋ฌด๋ฆฌ ์ธํ„ฐ๋„ท์ด ๋นจ๋ผ๋„ ๋น„๋™๊ธฐ ๋ฐฉ์‹์ธ JS๋Š” ์„œ๋ฒ„์˜ ์‘๋‹ต์„ ๋ฐ›๊ธฐ๋„ ์ „์— ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋˜๊ณ , ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ => ํŠน์ • ์‘๋‹ต์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด callback ๋ฐฉ์‹์„ ์‚ฌ์šฉ => ์ฝ”๋“œ ์ˆ˜ํ–‰ ์ˆœ์„œ๋ฅผ JS ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—๋งŒ ์˜์กดํ•˜์ง€ ์•Š์•„๋„ ๋จ
  • ๊ทธ๋Ÿฌ๋‚˜ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ์ข‹์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ, ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ

 

๐Ÿšฉ promise: ES6์—์„œ ์ถ”๊ฐ€๋œ JS ๋ฌธ๋ฒ•

  • new Promise๋กœ ์ƒˆ๋กœ์šด ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉ
  • promise๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ์ผ๋‹จ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ณ  ํ•ด๋‹น ์ž‘์—…์ด ์™„๋ฃŒ ์—ฌ๋ถ€๋ฅผ executor ๋งค๊ฐœ๋ณ€์ˆ˜(= resolve/reject)๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ
  • resolve: ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ˆ˜ํ–‰ ์™„๋ฃŒ๋˜๋ฉด ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ์Œ์„ resolve๋กœ ์ „๋‹ฌ, resolve๊ฐ€ ์‹คํ–‰๋˜๋ฉด then์œผ๋กœ ํ•ด๋‹น ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ
  • reject: ๋น„๋™๊ธฐ ์ž‘์—…์ด ์‹คํŒจํ–ˆ์„ ๋•Œ reject๋ฅผ callback์œผ๋กœ ์ „๋‹ฌ, catch๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ, ๋ณดํ†ต Error๋ผ๋Š” ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉ
  • finally: promise ์ฝ”๋“œ์˜ ์„ฑ๊ณต ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๋ฌด์กฐ๊ฑด์ ์œผ๋กœ ์‹คํ–‰. then, catch์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
const promise = new Promise((resolve, reject) => {
  console.log('Promise์˜ ๊ธฐ๋Šฅ์„ ๋ฐ”๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค');
  setTimeout(() => {
    // resolve('์ž‘์—… ์„ฑ๊ณต ์‹œ ๊ฒฐ๊ณผ๋ฅผ resolve๋กœ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค');
    const userId = 'bulsok';
    if (userId === 'bulsok') resolve(userId);
    else reject(new Error('์—๋Ÿฌ!'));
  }, 2000);
});
promise
  .then((value) => {
    console.log(`์š”์ฒญํ•˜์‹  ID๋Š” ${value}`);
  })
  .catch((err) => {
    console.log(err);
  })
  .finally(() => {
    console.log('Promise ์‹œํ€€์Šค ์ข…๋ฃŒ');
  });

 

๐Ÿšฉ Syntactic sugar

  • promise๋„ ์—ฌ๋Ÿฌ๋ฒˆ ์—ฐ๊ฒฐ๋˜๋ฉด chain์ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ œ๊ณตํ•˜๋Š” ๊ฒƒ => async/await
    • async: function ์•ž์— async๋ฅผ ๋ถ™์ด๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ promise๋ฅผ ๋ฐ˜ํ™˜, ๋‚ด๋ถ€์— await ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
    • await: promise๊ฐ€ ์™„์ „ํžˆ ์ˆ˜ํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์—ญํ• , ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ค‘์— cpu๋Š” ๋‹ค๋ฅธ ์ผ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„ ์—†์Œ