웹/Node.js
node.js 기본개념
ohojee
2023. 6. 16. 04:20
핵심개념
💡 node.js Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임
서버
- 네트워크를 통해 클라이언트에 정보나 서비스를 제공하는 컴퓨터 또는 프로그램
- 클라이언트 : 요청을 보내는 주체 ex)브라우저, 프로그램, 모바일 앱, 다른 서버
- 서버 : 클라이언트 요청에 대해 응답
자바스크립트 런타임
- 노드 : 자바스크립트 런타임(=자바스크립트 실행기)
- 런타임 : 특정 언어로 만든 프로그램들을 실행할 수 있는 환경
이벤트 기반
- 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식 ex)클릭, 네트워크 요청
- 특정 이벤트가 발생하면 무엇을 할지 미리 등록해두어야 함 ⇒ 이벤트 리스터에 콜백 함수를 등록하는 것
논 블로킹 I/O
- 이전 작업이 완료될 때까지 대기하지 않고 다음 작업 수행
- cf) 블로킹 : 이전 작업이 끝나야만 다음 작업 수행
- 블로킹 방식보다 논 블로킹 방식이 더 짧은 시간 안에 처리 가능
- 노드는 IO작업을 백그라운드로 넘겨 동시 처리
function longRunning() {
//오래걸리는 작업
console.log('작업 끝');
}
console.log('시작');
longRunning();
console.log('다음 작업');
작업 끝
시작
다음 작업
function longRunning() {
//오래걸리는 작업
console.log('작업 끝');
}
console.log('시작');
setTimeout(longRunning(), 0);
console.log('다음 작업');
작업 끝
다음 작업
시작
- setTimeout(콜백, 0) : 코드를 논 블로킹으로 만들기 위해 사용하는 기법 중 하나
- 코드를 논 블로킹 방식으로 짜더라도 코드 전체 소요시간이 더 짧아지지는 x 단지 실행순서만 바뀜
- 동기와 비동기 : 백그라운드 작업 완료 확인 여부 블로킹과 논 블로킹 : 함수가 바로 return되는지 여부
- 동기-블로킹 / 비동기-논 블로킹 방식이 대부분
- 동기-블로킹 : 백그라운드 작업 완료 여부를 계속 확인 호출한 함수가 바로 return되지 않고 백그라운드 작업이 끝나야 return
- 비동기-논 블로킹 : 호출한 함수가 바로 return되어 다음 작업으로 넘어감 백그라운드 작업 완료 여부는 신경 쓰지 않고 나중에 백그라운드가 알림을 줄 때 처리
알아야할 자바스크립트 문법
ES2015
- 2015년을 기점으로 매년 자바스크립트 문법 변경사항 발표
const vs let
if (true) {
var x = 3;
}
console.log(x)
if (true) {
const y = 3;
}
console.log(y)
//x는 출력이 되지만 y는 Uncaught ReferenceError: y is not defined 오류 발생
- var 은 함수 스코프 가짐 ⇒ if 문의 블록과 관계없이 접근 o
- const와 let은 블록 스코프 가짐 ⇒ 블록 밖에서는 변수에 접근 x
- const vs let
const a = 0 a = 1 //Uncaught TypeError: Assignment to constant variable. let b = 0 b = 1 const c //Uncaught SyntaxError: Missing initializer in const declaration
- const : 상수 ⇒ 초기화할 때 값 할당 후, 그 후로 변경 불가
- 기본적으로 const를 사용하고 다른 값을 할당해야 한다면 let 사용
템플릿 문자열
var string = `${n1} + ${n2}`
- `을 이용하여 변수를 ${} 안에 넣을 수 o
- 작은 따옴표와 큰 따옴표도 함께 사용 가능
화살표 함수
function add(x, y) {
return x + y
}
const add1 = (x, y) => {
return x + y
}
프로미스
- 콜백지옥 현상 극복
const condition = true; //true면 resolve, false면 reject
const promise = new Promise((resolve, reject) => { //promise 생성, resolve와 reject를 매개변수로 갖는 콜백함수 넣음
if (condition) {
resolve('success')
} else {
reject('fail')
}
})
promise
.then((msg) => {
console.log(msg) //success한 경우, resolve한 경우 실행, success 출력
})
.catch((err) => {
console.log(err) //fail인 경우, reject한 경우 실행, fail 출력
})
.finally(() => {
console.log('must') //성공 실패 관계없이 끝나고 무조건 실행
})
- 프로미스 객체 먼저 생성
- 실행은 바로 하되 결괏값은 나중에 받는 객체, then이나 catch를 통해 받음
promise
.then((msg) => {
return new Promise((resolve, reject) => {
resolve(msg)
})
})
.then((msg2) => { //위의 msg가 msg2로 들어옴
console.log(msg2)
return new Promise((resolve, reject) => {
resolve(msg2)
})
})
.then((msg3) => {
console.log(msg3)
})
.catch((err) => {
console.log(err) //fail인 경우, reject한 경우 실행, fail 출력
})
- then에서 resolve한 것을 다음 then에서 매개변수로 받을 수 o 이 경우에 반드시 new Promise를 return해야 함
async/await
function findAndSaveUser(Users) {
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user) => {
return Users.findOne({ gender: 'm' });
})
.then((user) => {
// 생략
})
.catch(err => {
console.error(err);
});
}
const findAndSaveUser = async (Users) => {
try {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm' });
// 생략
} catch (error) { //promise가 reject된 경우
console.error(error);
}
};
- 위의 promise문을 아래처럼 간결하게 바꿀 수 o
- 해당 프로미스가 resolve될 때까지 기다린 후 다음 로직으로 넘어감 await Users.findOne({})이 resolve될 때까지 기다린 다음 user 변수 초기화