Node.js
란 구글의 V8 자바스크립트 엔진 기반인 server-side scripting
이다.
Node.js
로 만들 수 있는 프로그램:
Node.js
는 I/O 및 많은 클라이언트 연결과 관련하여 매우 효율적이다. 그러나 단일 쓰레드이기 때문에 CPU intensive한 작업엔 효율적이지 않다.
일정 시간 이후 콜백 함수 실행
setTimeout은 함수의 참조 값을 받도록 정의되어 있는데 함수 뒤에 ( )를 붙여 인수로 전달하면 함수 실행 결과가 전달되어 버린다. 그런데 반환문이 없다면 호출 결과는 undefined가 되어 스케줄링할 대상을 찾지 못해, 원하는 대로 코드가 동작하지 않는다.
일정 시간 마다 콜백 함수를 반복
재귀적인 setTimeout vs. setInterval
setInterval 의 경우 콜백 함수의 실행에 의해 소비되는 일부의 interval 때문에 진짜 딜레이는 기재 된 것 보다 짧거나 길 수도 있다.
반면 재귀적인 setTimeout은 setInterval이 보장하지 못하는 실행간 딜레이를 보장할 수 있다.
콜백 함수를 즉시 실행
setImmediate()
는 현재 이벤트 루프 주기 끝에 코드를 실행한다. 이 코드는 현재 이벤트 루프의 모든 I/O 작업 후 다음 이벤트 루프에 스케줄링 된 모든 타이머 이전에 실행된다.
setTimeout(func,0) vs setImmediate
파일 시스템 접근, 네트워크 같은 I/O 작업의 콜백 함수 안에서 타이머를 호출하는 특수한 경우엔setImmediate
가 먼저 실행 된다. 하지만 항상 그런 것은 아니며 솔직히 잘 모르겠으니 그냥setImmediate
쓰자...
두가지의 함수가 존재: Blocking 함수, Non-Blocking 함수
Node.js 프로세스에서 추가적인 JavaScript의 실행을 위해 JavaScript가 아닌 작업이 완료될 때까지 기다려야만 하는 상황
이는 이벤트 루프가 블로킹 작업을 하는 동안 JavaScript 실행을 계속할 수 없기 때문
예:
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // 파일을 읽을 때까지 여기서 블로킹
Non-blcoking 함수에선 I/O 작업이 멈추지 않고 비동기적으로 실행된다.
예:
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
if (err) throw err;
console.log(data);
});
NodeJS에서 Javascript는 싱글 쓰레드(single thread)로 수행된다. 그래서 NodeJS에서 동시성이라 함은 다른 일을 마친 후, Javascript 콜백 함수를 수행하는 이벤트 루프의 수용량 말하는 것이다. 따라서 동시성을 높이기 위해 동시에 실행시킬 코드는 I/O와 같은 non-Javascript 연산이 일어날 때, 이벤트 루프가 계속 실행되도록 해주는 것이 좋다.
예를 들어 웹 서버에 대한 각 요청을 수행하는데 50ms가 걸릴 때 database I/O가 45ms 걸리고, 비동기적으로 처리한다고 생각하보자. 이렇게 non-blocking 비동기 연산 방식이기 때문에 45ms 동안 다른 일을 할 수 있게 되고 따라서 그 동안에 다른 요청을 처리할 수 있다. 이 점 때문에 blocking 함수 대신 non-blocking 함수를 사용하게 되면 더 많은 요청을 처리할 수 있다.