Intro
Node.js는 무엇인지?
Node.js는 크롬 V8 JavaScript엔진으로 빌드된 JS의 런타임으로, 브라우저에서만 작동이 가능했던 JS를 브라우저 없이도 작동하도록 만든 환경이다.
Node.js는 논블로킹(non-blocking) I/O, 싱글 스레드(single thread), 이벤트 루프(event loop)의 특성이 있다.
- 비동기 언어의 대표주자인 JavaScript에 논블로킹(non-blocking) 특성을 가진 Node.js가 만나 여러가지 일을 한번에 처리할 수 있는 유연한 프로그래밍이 가능해진거다.
- 그렇지만, Node.js가 논블로킹 특성을 가지고 있음에도 불구하고, 싱글 스레드(single thread)를 사용한다.
- 싱글 스레드의 장점
- 스레드 생성 부하 및 스래드 유지에 대한 부담 없이 같은 컴퓨팅 리소스라도 더 효율적으로 사용이 가능하다.
- 스레드들이 공유하는 자원에 대한 동시접근 문제 (Race condition) 상황이 발생하지 않는다. => 공유자원이 없어 여러 스레드가 하나의 오류로 인해 모두 문제를 일으키는 상황이 발생하지 않는다.
- Node.js는 스레드를 늘리기 보다, 새로운 프로세서를 생성해 확장을 도모하는데, 프로세서들은 스레드에 비해 독립적이어서, 하나의 프로세스가 문제를 일으켜도 다른 프로세스까지 종료될 확률이 상대적으로 낮다. 이러한 특징 때문에 서버 확장이 매우 자유롭다. (유지보수 비용, 개발 속도, 확장성 등의 이유로 많은 스타트업에서 Node.js를 선호한다)
- 싱글 스레드의 단점
- 멀티 스레드 대비 연산 효율이 떨어지는데, 이 때문에, CPU intensive한 작업에 효율적이지 못함
- 싱글 스레드의 장점

- 이벤트 루프(event loop)는 위와 같은 싱글 스레드의 연산 효율 측면에서의 단점을 극복하게 해주는 특성이다.
- 사실, 이벤트 루프는 개념이 어렵고 딥해서, 거의 이해한 내용이 없다...ㅋㅋㅋ
- 매니저님께 물어보니, 지금은 이벤트 루프라는 것이 있다는 것만 알면 충분하고, 지금은 이해를 하기에는 너무 어려운 내용이니 나중에 다시 보라고 하셨다.
- 아래는 나중에 참고할 이벤트루프 관련해서 정리가 잘 되어 있는 블로그와 공식문서다 (읽어도 모르겠다는 건 함정..)
Node.js 이벤트 루프(Event Loop) 샅샅이 분석하기
글에 들어가기에 앞서 Node.js의 이벤트 루프의 경우 공식 문서에 설명이 부족하고 이에 따라 여러 사람들이 각자 나름대로 분석한 글이 많아 무엇이 이벤트 루프의 정확한 동작인지 알기 힘듭니
www.korecmblog.com
Node.js 이벤트 루프, 타이머, `process.nextTick()` | Node.js
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
nodejs.org
Node.js 이벤트루프 제대로 이해하기
이 글은 Daniel Khan의 What you should know to really understand the Node.js Event Loop 글을 번역 한 글입니다. 모든 저작권과 권리는 Daniel Khan에게 있습니다. 곳곳에 의역이 들어가있는 점 양해부탁 드립니다 :) No
tk-one.github.io
Body
동기 / 비동기 vs 블로킹 / 논블로킹 I/O
동기와 비동기는 전에도 한번 다뤘던 개념이랑 대충 무슨 느낌인지는 알겠는데, 블로킹과 논블로킹 I/O는 뭔지 도통 감이 안 잡혔다. 그런데, 두 개념에 대해 진짜 쉽고 한번에 이해할 수 있게 작성해 놓은 블로그가 있었다!
이 글 작성자 분께 무한 감사...! 참고로, 예제 코드 보면서 빵 터졌다ㅋㅋ
👩💻 동기 & 비동기 / 블로킹 & 논블로킹 💯 완벽 이해하기
동기 & 비동기 vs 블로킹 & 논블록킹 개념 이 개념들을 처음 접하거나 컴퓨터 공학에 대해 잘 모르는 사람은 이 개념들이 서로 뭔가 연관이 있는 것으로 오해하기 쉽다. 아무래도 동기와 블록킹,
inpa.tistory.com
- 동기/비동기 : 프로세스의 수행 순서 보장에 대한 매커니즘으로, 리턴값이 중요함
- 동기 : A함수가 B함수를 호출했다면, A함수는 B 함수의 리턴과 작업 완료 여부를 계속해서 확인
- 비동기: A함수가 B함수를 호출했다고 하더라도, A함수는 B함수의 리턴과 작업 완료 여부를 학인하지 않음
- 블로킹/논블로킹 : 프로세스의 유휴 상태에 대한 개념으로, 제어권이 중요함
- 제어권이란 함수를 실행할 수 있는 권리와 같은 것인데, 제어권을 가진 함수는 자신의 코드를 끝까지 실행한 후, 제어권을 자시을 호출한 함수에게 돌려줌
- 블로킹 : A함수가 B함수를 호출할 때, 자신이 가지고 있던 제어권을 B함수에게 넘기는 경우를 블로킹이라고 말하는데, B함수를 호출하면서 제어권을 넘겨줬기 때문에, A함수는 B함수가 종료되고 제어권을 돌려 받기까지 함수 실행을 멈춤
- 논블로킹 : A함수가 B함수를 호출할 때, 자신의 제어권을 넘기지는 않고, B함수를 실행만 시킴. A함수는 B함수의 실행/종료와 상관 없이 계속 자신의 코드를 실행 (제어권을 가지고 있으면 콜백으로 하위 함수를 실행시킬 수 있음)
위의 개념들은 현실에서 동기+블로킹, 동기+논블로킹, 비동기+논블로킹의 조합으로 쓰임

- 동기 + 블로킹
- 리턴 값이 중요한 동기와 제어권을 호출한 B함수에 넘기는 블로킹의 조합
- 일반적으로 많이 이해하고 있는 동기 방식
- A가 B를 호출하면, A가 B의 리턴값과 종료여부를 계속 확인하면, 제어권을 B에게 넘겼기 때문에, B함수가 종료될 때까지 A함수는 기다린다.
- 예를 들자면, 직장에서 상사에게 내가 보고서를 올렸는데, 상사가 나에게 검토가 다 끝날 때까지 기다리라고 하는 상황과 같다. 상사가 검토를 마치고 자신의 결과 값을 나에게 줄때까지 나는 다른 일을 할 수 없다ㅠㅠ
function employee () {
for (let i = 1; i < 101; i++) {
console.log(`직원: 인형 눈알 붙히기 ${i}번 수행`);
}
}
function boss () {
console.log('사장: 출근');
employee();
console.log('사장: 퇴근');
}
boss();
/*
사장: 출근
직원: 인형 눈알 붙히기 1번 수행
직원: 인형 눈알 붙히기 2번 수행
...
직원: 인형 눈알 붙히기 100번 수행
사장: 퇴근
*/
- 동기 + 논블로킹 (커피 주문을 받으면서 동시에
- 리턴 값이 중요한 동기와 제어권을 호출한 B함수에게 넘기지 않는 논블로킹의 조합
- 위의 경우와는 달리, 이번에는 A가 B를 호출하지만, A는 B의 리턴 값과 종료 여부를 계속 체크하면서, B의 작업이 끝나기를 기다리지 않고 동시에 자신의 코드를 수행
- 이번에는 직장에서 상사가 보고서를 전달 받고, 나에게 가서 볼 일을 보라고 한 상황이다. 나는 상사의 지시대로 자리에 가서 다른 일을 수행하지만, 조바심이 많은지라, 중간 중간 상사가 검토 다 마쳤는지 확인한다.
function* employee () {
for (let i = 1; i < 101; i++) {
console.log(`직원: 인형 눈알 붙히기 ${i}번 수행`);
yield;
}
return;
}
function boss () {
console.log('사장: 출근');
const generator = employee();
let result = {};
while (!result.done) {
result = generator.next();
console.log(`사장: 유튜브 시청...`);
}
console.log('사장: 퇴근');
}
boss();
/*
사장: 출근
직원: 인형 깔알 붙히기 1번 수행
사장: 유튜브 시청...
직원: 인형 눈알 붙히기 2번 수행
사장: 유튜브 시청...
...
직원: 인형 눈알 붙히기 100번 수행
사장: 유튜브 시청...
사장: 퇴근
*/
- 비동기 + 논블로킹 (JavaScript + Node.js)
- 리턴 값이 중요하지 않은 비동기와 제어권을 호출한 B함수에 넘기지 않는 논블로킹의 조합
- 이번에는 A가 B를 호출하지만, A는 B의 리턴과 종료에 관심이 없으며, 각자 코드를 수행하는 경우다.
- 이 경우에 A는 B, C, D, ... 등 여러 콜백함수를 한번에 실행시킬 수도 있다.
- 직장을 예로 들자면, 어제 B 상사가 부탁한 보고서를 제출하고, 나와서 B상사가 검토를 하는지 안 하는지 더이상 신경쓰지 않고 C 상사가 시킨 일을 처리하는 중이다.
function employee (maxDollCount = 1, callback) {
let dollCount = 0;
const interval = setInterval(() => {
if (dollCount > maxDollCount) {
callback();
clearInterval(interval);
}
dollCount++;
console.log(`직원: 인형 눈알 붙히기 ${dollCount}번 수행`);
}, 10);
}
function boss () {
console.log('사장: 출근');
employee(100, () => console.log('직원: 눈알 결산 보고'));
console.log('사장: 퇴근');
}
boss();
/*
사장: 출근
사장: 퇴근
직원: 인형 눈알 붙히기 1번 수행
직원: 인형 눈알 붙히기 2번 수행
...
직원: 인형 눈알 붙히기 100번 수행
직원: 눈알 결산 보고
*/
- 비동기 + 블로킹 (굳이 이렇게?? 용례 없음)
- 리턴 값이 중요하지 않은 비동기와 제어권을 호출한 B함수에게 넘기는 조합 =>
- 비동기기 때문에, B함수의 상태를 확인하지는 않지만, B함수의 작업이 끝날 때까지 A함수는 기다려야 하기 때문에, 위에서 본 동기+블로킹과 거의 비슷한 상황이다.
- 이 조합은 개발자의 실수로 구현되는 경우를 제외하고는 사용되지 않는다고 한다.
사용한 모든 샘플 코드는 위에서 소개한 블로그에서 가져왔다
👩💻 동기 & 비동기 / 블로킹 & 논블로킹 💯 완벽 이해하기
동기 & 비동기 vs 블로킹 & 논블록킹 개념 이 개념들을 처음 접하거나 컴퓨터 공학에 대해 잘 모르는 사람은 이 개념들이 서로 뭔가 연관이 있는 것으로 오해하기 쉽다. 아무래도 동기와 블록킹,
inpa.tistory.com
'항해99_10기 > 105일의 TIL & WIL' 카테고리의 다른 글
| [2주차 WIL] 2022.11.21 ~ 2022.1126 회고 (0) | 2022.11.27 |
|---|---|
| [3주차] [20221127] for, for in, for of (0) | 2022.11.27 |
| [2주차] [20221124] 탐욕법, 그래프 자료구조 (0) | 2022.11.25 |
| [2주차] [20221123] 화살표 함수의 this binding (0) | 2022.11.24 |
| [2주차][20221122] 알고리즘 문제 풀이 (0) | 2022.11.23 |