항해 99 3주차 - Node.js

youngsung·2023년 2월 24일
0

Node.js

목록 보기
1/7

Node.js란?

Node.js는 Chrome V8 JavaScript엔진으로 빌드된 JavaScript런타임입니다.브라우저가 없어도 동작할수있는게 Node.js입니다

Node.js를 굳이 사용해야 하는 이유는?

  • Node.js를 3가지 특성으로 나누자면
    1} 논 블로킹(Non-blocking)I/O :
    기존의 블로킹(Blocking)I/O는 프로그램 내부에서 함수를 호출하면 호출된 함수가 작업을 마칠 때까지 대기하는 방식이었지만, 논 블로킹(Non-blocking)I/O는 함수가 실행되는 중에도 다른 작업을 동시에 진행할 수 있는 장점이 있습니다.(비동기 작업을 할때 좀 더 효율적으로 사용할수있는 특성입니다.)
    2} 싱글 스레드(Single Thread)
    스레드 하나를 사용하는 것이며, 동시에 하나의 작업만을 처리할 수 있습니다.
    3} 이벤트 루프(Event Loop)
    Javascript가 가지고 있던 싱글 스레드의 약점을 극복하기 위해 효율적으로 작업을 처리할 수 있는 특성입니다.

NVM으로 Node.js 버전관리하기

nvm설치이후,

버전 확인을 합니다.

nvm ls

nvm 버전 리스트를 통해 다운받은 버전을 확인해봅니다.

nvm install [내가 다운받고자 하는 버전]

만약 여러개의 버전을 다운받아서 원하는 버전을 사용하고 싶으면,

nvm use [해당 사용하고자하는 버전]

이렇게 쉽게 노드의 버전을 변경할수 있습니다.


동기(Sync) & 비동기(Async)

동기(Sync)와 비동기(Async)에 대한 개념

  • 동기 : 먼저 실행된 코드의 결과가 나올때까지 대기하는것을 말합니다.
  • 비동기 : 실행된 순서와 관계 없이 결과가 나오는것을 말합니다.

Blocking Model & Non-Blocking Model

  • Blocking Model : 코드의 실행이 끝나기 전까지 실행 제어권을 다른곳에 넘기지 않아 다른 작업을 하지 못하고 대기 하는것을 말합니다.

  • Non-blocking Model : 코드의 실행이 끝나지 않아도 실행 제어권을 다른곳에 넘겨 다음 코드가 실행될 수 있는것을 말합니다.

  • 자바스크립트는 Async + Non-Blocking Model을 채용하여 현재 실행중인 코드의 실행이 끝나지 않아도 다음 코드를 호출합니다.

프로미스(Promise)

  • 자바스크립트에서 비동기 처리를 동기로 처리할 수 있게 돕는 객체 유형입니다.
    이 객체를 이용하면 비동기 처리를 아주 손쉽게 할 수 있습니다.

  • Promise생성자 인터페이스
    executor에는 함수만 올 수 있으며 인자로 resolve, reject가 주입됩니다.

  • executor는 Promise의 실행 함수라고 불리고, Promise가 만들어질 때 자동으로 실행됩니다.
    Promise가 연산을 언제 종료하는지 상관하지 않고, resolve, reject 중 하나를 무조건 호출해야합니다.

new Promise(executor);

// 예제
new Promise((resolve, reject) => {
	// 명령문 
});
  • Promise의 상태
    Promise는 반드시 3가지 상태를 지니며, 대기(Pending)상태가 아니라면 Promise 연산이 이미 끝난 상태로 볼 수 있습니다.
    • 대기(Pending) : 이행하거나 거부되지 않은 초기 상태.
    • 이행(Fulfilled) : 연산이 성공적으로 완료됨.
    • 거부(Rejected) : 연산이 실패함.
  • Promise가 만들어 질 때 executor가 실행되며, exeutor에서 resolve함수가 호출되기 전까지 firstPromise.then(...)안에 있는 코드를 실행하지 않습니다.
    이렇게 exeutor가 실행되어 resolve된 프로미스를 Fulfilled Promise라고도 부릅니다.
const timerPromise = new Promise((resolve, reject) => { // 이곳에 정의된 함수가 executor
  setTimeout(() => {
	  console.log('First');
		resolve();
	}, 1000);
});

// 이 시점에서 timerPromise는 Fulfilled Promise라고 부를 수 있다.

timerPromise.then(() => {
	console.log('Middle');
	console.log('Last');
});

// Print: First
// Middle
// Last
  • Promise.then
    Promise 안에서 resolve가 실행 된 경우 then 메서드에 작성된 함수가 실행됩니다.
const resolvePromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('First');
    resolve('Resolve!'); // resolve를 실행할 때, 안에 데이터를 넣어줄 수 있습니다.
  }, 1000);
});

resolvePromise.then((data) => {
  console.log('Middle');
  console.log('Last');
  console.log(data);
})

// Print: First -> 1초 뒤에 출력됩니다.
// Middle
// Last
// Resolve!
  • Promise.catch
    Promise 안에서 에러가 throw되거나 reject가 실행되면 catch 메서드에 작성한 함수가 실행됩니다.
const errorPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
	  console.log('First');
		reject('Error!!'); // 직접 reject를 실행하면 프로미스에서 에러가 발생한것으로 간주됩니다.
	}, 1000);
});

errorPromise.then(() => {
	console.log('Middle');
	console.log('Last');
}).catch((error) => {
	console.log('에러 발생!', error);
});

// Print: '에러 발생! Error!!'
  • 비동기 함수

    • 특징
      비동기 함수는 일반 함수나 화살표 함수와 아주 비슷하지만 딱 두가지만 다릅니다.
      1) 비동기 함수의 결과 값은 항상 Promise객체로 resolve된다.
      2) 비동기 함수 안에서만 await 연산자를 사용할 수 있다.

      이 두가지 특징을 제외하면 기존처럼 일반 함수나, 화살표 함수처럼 사용할 수 있습니다.

      // 비동기 + 일반 함수
      async function 함수이름() {
          // 명령문
      }
      
      // 비동기 + 익명 함수
      async function() {
        // 명령문
      }
      
      // 비동기 + 화살표 함수
      async () => {
          // 명령문
      }
    • 비동기 함수는 왜 쓸까?
      await 연산자를 비동기 함수 안에서만 사용할 수 있는데, 이를 활용하면 문법이 훨씬 간결해집니다.

    • new Promise(executor)코드로 Promise를 직접 생성하면 executor가 바로 실행되는것과 달리, 비동기 함수는 함수가 실행되기 전까지 Promise를 생성하지 않습니다.

  • await 연산자

    • await 연산자를 사용하면 Promise가 fulfill 상태가 되거나 rejected될 때 까지 함수의 실행을 중단하고 기다릴 수 있습니다.
    • await 연산자는 async 함수 안에서만 사용할 수 있습니다.
      const result = await;

객체 리터럴

  • 객채(Object)
    Javascript의 데이터 타입은 크게 원시 타입과 객체 타입으로 분류됩니다.

    • 원시 타입은 단 하나의 값만을 나타내고, 원시 타입의 값은 변경이 불가능 한 값입니다.

    • 객체 타입은 다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료 구조이고, 객체 타입의 값을 변경 가능한 값입니다.

      	javascript는 객체 기반의 프로그래밍 언어이고, javascript를 구성하는 거의 모든 것은 객체로 구성되어 있습니다. 객체(Object)는 0개 이상의 프로퍼티로 구성된 집합이며, 하나의 프로퍼티는 Key와 Value로 구성되어 있습니다.
  • 객체 리터럴 이란?
    리터럴(literal)은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법 입니다.
    객체 리터럴은 객체를 생성하기 위해 Class를 먼저 선언하고 new 연산자와 함께 생성자를 호출할 필요가 없이 일반적인 숫자, 문자열을 만드는것과 유사하게 객체를 생성할 수 있습니다.

  • 객체 리터럴로 객체 생성하기

    • 객체 리터럴은 중괄호{} 내에 0개 이상의 프로퍼티를 정의해서 선언합니다.
  • 프로퍼티(Property)란?
    객체의 상태를 나타내는 값(Data)입니다.
    프로퍼티는 키(Key)와 값(Value)으로 구성되어 있습니다.

  • 메서드(Method)란?
    프로퍼티를 참조하고 조작할 수 있는 동작(behavior)을 나타냅니다.
    객체의 프로퍼티 값이 함수로 구성되어 있을 경우 메서드(Method)라고 부릅니다.

    let objectLiteral = {
        key: 'Value', // 프로퍼티
        helloWorld: function () { // 메서드
            return "Hello world";
        }
    };
    
    console.log(objectLiteral.helloWorld()); // Hello world

Error handling

  • 에러 핸들링(error handling)이란?
    에러 핸들링은 에러를 관리하는 방법이고, 예상치 못한 상황에 대처하는 방식입니다.
    에러는 예상할 수 있는 에러와 예상치 못한 에러로 구분할 수 있는데, 일반적인 어플리케이션을 설계할 때에는 예상치 못한 에러 상황이 더욱 많이 일어날 것으로 가정해야 합니다.
    프로그래머가 작성한 코드에 예상치 못한 에러가 일어날 가능성은 언제나 존재하고, 이러한 에러 상황을 대비해 언제든지 처리할 수 있어야 합니다.

  • try / catch
    서버에서 에러가 발생하지 않게 하기 위해서 예외 처리를 진행합니다.
    예외 처리는 일반적으로 try ... catch문을 사용합니다.

    const users = ["Lee", "Kim", "Park", 2];
    
    try {
      for (const user of users) {
        console.log(user.toUpperCase());
      }
    } catch (err) {
      console.error(`Error: ${err.message}`);
    }
    
    // LEE
    // KIM
    // PARK
    // Error: user.toUpperCase is not a function
  • throw
    프로그래머의 입장에서 에러는 고의로 에러를 발생시키기도 해야합니다.

    예를 들어서 은행 어플리케이션의 현금 인출 서비스를 만든다고 할 때, 계좌의 잔고가 요청받은 금액보다 적다면 throw를 호출하면 그 즉시 현재 실행되고 있는 함수는 실행을 멈추게 됩니다.

    function withdraw(amount, account) {
      if (amount > account.balance)
        throw new Error("잔고가 부족합니다.");
      account.balance -= amount;
        console.log(`현재 잔고가 ${account.balance}남았습니다.`); // 출력되지 않음
    }
    
    const account = { balance: 1000 };
    withdraw(2000, account);
    
    // Error: 잔고가 부족합니다.
  • finally
    try에서는 HTTP연결이 되고 있거나 파일과 같은 특정한 '자원'을 가지고 처리할 때가 있습니다. 하지만 해당 '자원'을 계속 가지고 있으면, 무의미한 메모리를 차지하게 될 것 이므로 에러 여부와 상관없이 일정 시점에서는 해당 '자원'을 삭제 시켜야합니다.

    function errorException(isThrow) {
      try {
        console.log('자원을 할당하였습니다.');
        if (isThrow) throw new Error();
      } catch (error) {
        console.log('에러가 발생했습니다.');
      } finally {
        console.log('자원을 제거하였습니다.');
      }
    }
    
    errorException(false);
    // 자원을 할당하였습니다.
    // 자원을 제거하였습니다.
    errorException(true);
    // 자원을 할당하였습니다.
    // 에러가 발생했습니다.
    // 자원을 제거하였습니다.

클래스(Class)

  • 클래스(Class)란?
    - 클래스는 정보를 묶는 것입니다!
    • 현실과 비슷한 개념(객체)을 나타내기 위한 도구를 클래스(Class)라고 부릅니다.

    • 클래스는 미리 정의해놓으면 필요할 때마다 해당 클래스로 동일한 틀을 가진 객체를 만들 수 있습니다.

      • 여기서 동일한 클래스를 이용해 생성한 객체를 인스턴스(Instance)라고 부릅니다.
  • 생성자(Constructor)

    "클래스 내부에서 constructor()로 정의한 메서드를 "생성자"라고 부릅니다.

  • this와 프로퍼티(Property)
    생성자의 바디에서 this 키워드를 사용합니다. 이 this는 클래스를 사용해 만들어 질 객체 자신을 의미하고 this 뒤에 붙는 name, age, tech는 클래스를 이용해서 만들어질 객체의 속성(Property)입니다.

    class User {
      constructor(name, age, tech) { // User 클래스의 생성자
        this.name = name;
        this.age = age;
        this.tech = tech;
      }
    }
    
    const user = new User("이용우", "28", "Node.js"); // user 인스턴스 생성
    console.log(user.name); // 이용우
    console.log(user.age); // 28
    console.log(user.tech); // Node.js
    • 생성자를 이용해 name, age, tech인자값을 입력받아 class 내부변수에 저장합니다.
  • 메서드 (Method)
    자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값으로 사용할 수 있습니다. 프로퍼티 값이 함수일 경우에는 일반 함수와 구분하기 위해 메서드(Method)라고 부릅니다.
    즉, 메서드는 객체(Object)에 묶여 있는 함수를 의미합니다.
    클래스에서도 데이터를 나타내는 속성뿐만아니라 함수와 같이 특정 코드를 실행할 수 있는 문법을 사용할 수 있습니다. 여기서는 Class라는 객체(Object)에 묶여있는 함수를 메서드(Method)라고 부릅니다.

    class User {
      constructor(name, age, tech) { // User 클래스의 생성자
        this.name = name;
        this.age = age;
        this.tech = tech;
      }
    
      getName() { return this.name; } // getName 메서드
      getAge() { return this.age; }  // getAge 메서드
      getTech() { return this.tech; } // getTech 메서드
    }
    
    const user = new User("이용우", "28", "Node.js"); // user 인스턴스 생성
    console.log(user.getName()); // 이용우
    console.log(user.getAge()); // 28
    console.log(user.getTech()); // Node.js
  • 상속이란?
    일반적으로 클래스의 인스턴스는 선언한 클래스의 기능을 모두 상속합니다.
    상속을 이용해 부모클래스와 자식 클래스로 나뉠 수 있습니다. 부모 클래스의 경우 메서드, 내부 변수와 같은 정보를 자식 클래스에게 할당해줄 수 있습니다.

    class User { // User 부모 클래스
      constructor(name, age, tech) { // 부모 클래스 생성자
        this.name = name;
        this.age = age;
        this.tech = tech;
      }
      getTech(){ return this.tech; } // 부모 클래스 getTech 메서드
    }
    
    class Employee extends User{ // Employee 자식 클래스
      constructor(name, age, tech) { // 자식 클래스 생성자
        super(name, age, tech);
      }
    }
    
    const employee = new Employee("이용우", "28", "Node.js");
    console.log(employee.name); // 이용우
    console.log(employee.age); // 28
    console.log(employee.getTech()); // 부모 클래스의 getTech 메서드 호출: Node.js
profile
To Infinity and Beyond

0개의 댓글