Node.js 기본
- 노드는 서버가 아님. 자바스크립트 엔진은 V8
- 노드는 크롬 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임(실행기)이다.
- 런타임 : 특정 언어로 만든 프로그램들을 실행할 수 있게 해주는 가상 머신(크롬의 V8 엔진 사용)의 상태
- 노드를 통해 JS로 만든 프로그램들을 실행할 수 있고 덕분에 HTML과 브라우저의 종속성에서 벗어남
- 타입스크립트 런타임은 Deno.js
노드의 특징
1. 이벤트 기반
이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식
- 이벤트의 예 : 클릭, 네트워크 요청, 타이머 등
- 이벤트 리스너 : 이벤트를 등록하는 함수
- 콜백 함수 : 이벤트가 발생했을 때 실행될 함수
2. 논블로킹 I/O
- 논 블로킹 :오래 걸리는 함수를 백그라운드로 보내서 다음 코드가 먼저 실행되게 하고, 나중에 오래 걸리는 함수를 실행
- 논블로킹 방식 하에서 일부 코드(I/O작업-파일 시스템 접근, 네트워크 요청 / 압축 / 암호화 등)는 백그라운드에서 병렬로 실행됨
- 나머지 코드는 블로킹 방식으로 실행됨
- ∴ I/O 작업이 많을 때 노드 활용성이 극대화
- 노드는 동기이면서 블로킹 / 비동기이면서 논블로킹 각각이 짝이라고 생각하면 된다.
- 동기 & 블로킹 -> 코드가 순서대로 실행 -> 실행 컨텍스트
- 비동기 & 논블로킹 -> 순서대로 실행 X. 그치만 순서대로 실행되지 않는 것들 안에서도 규칙이 있음 -> 이벤트루프
3. 프로세스 vs 스레드
프로세스와 스레드
- 프로세스 : 운영체제에서 할당하는 작업의 단위. 프로세스 간 자원 공유 안함
프로그램 하나 켤때마다 프로세스가 하나씩 뜨는 것
- 스레드 : 프로세스 내에서 실행되는 작업의 단위, 부모 프로세스 자원 공유
- 노드 프로세스는 멀티 스레드이지만 직접 다룰 수 있는 스레드는 하나이기 때문에 싱글 스레드라고 표현
- 노드는 주로 멀티 스레드 대신 멀티 프로세스 활용
- 노드는 14버전부터 멀티 스레드 사용 가능
- 멀티스레드로 코딩하기는 사람의 머리로는 상당히 어렵다
- 결국 노드는 싱글스레드이고 그것을 어떻게 효율적으로 관리하는지
노드의 역할
1. 서버로서의 노드
- 서버 : 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램
- 클라이언트 : 서버에 요청을 보내는 주체 (브라우저, 데스트탑 프로그램, 모바일 앱 등)
- 노드는 서버가 아니다, 하지만 노드는 서버를 구성할 수 있게 하는 모듈을 제공한다
2. 노드 서버의 장단점
- CPU 작업을 위해 AWS Lambda나 Google Cloud Functions 같은 별도 서비스 사용
- 페이팔, 넷플릭스, 나사, 월마트, 링크드인, 우버 등에서 메인 또는 서브 서버로 사용
3. 서버 외의 노드
- 자바스크립트 런타임이기 때문에 용도가 서버에만 한정되지 않음
- 웹, 모바일, 데스크탑 애플리케이션에도 사용
- 웹 프레임워크 : Angular, React, Vue, Meteor 등
- 모바일 앱 프레임워크 : React Native 등
- 데스크탑 개발 도구 : Electron(Atom, Slack, VSCode, Discord 등 제작)
호출 스택
- 파일이 실행되면
anonymous
라는 것이 호출스택 맨 밑에 깔리고 함수가 실행되면 이 위에 차곡차곡 쌓인다
- 이 호출스택이 쌓였다가 다 없어지면 코드가 완전히 실행된 것
var, const, let
- const는 이
블록스코프
를 못 빠져 나간다
- var는
블록스코프
는 빠져나가지만 함수스코프
는 못빠져 나간다
var은 함수스코프를 존중하고 const는 블록스코프를 존중한다
화살표 함수
function add1(x, y) {
return x + y;
}
const add2 = (x, y) => {
return x + y;
}
const add3 = (x, y) => (x + y);
this가 있는 경우 -> 구조분해 할당 비추천
promise 프로미스
- 콜백 헬이라고 불리는 지저분한 자바스크립트 코드의 해결책
- 프로미스란? -> 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체
- then을 붙이면 결과를 반환함
- 실행이 완료되지 않았으면 완료된 후에 then 내부 함수가 실행됨
- resolve(성공리턴값) -> then 으로 연결
- reject(실패리턴값) -> catch 로 연결
- finally 부분은 무조건 실행됨
- Promise.resolve(성공리턴값) : 바로 resolve하는 프로미스
- Promise.reject(실패리턴값) : 바로 reject하는 프로미스
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
Promise.all([promise1, promise2])
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error);
})
- Promise.all(배열) : 여러 개의 프로미스를 동시에 실행
- 하나라도 실패하면 catch로 감
- allSettled로 실패한 것만 추려낼 수 있음