Node.js 기술 면접 관련하여 정리한 글로, version을 나눠서 업데이트할 예정이다.
Chrome V8 Javascript 엔진으로 빌드된 Javascript 런타임이다. 여기서 V8 엔진이 다른 JS 엔진보다 속도가 빠르다. 런타임은 프로그래밍 언어가 구동되는 환경을 뜻하는데 Node.js는 Javascript를 구동시키는 환경이다.
Chrome V8 Javascript 엔진을 기반으로 동작을 한다. 싱글 스레드 기반의 이벤트 루프가 돌면서 요청을 처리하고, 시스템적으로 Non-Blocking I/O를 지원하지 않는 I/O 호출이 있을 경우에는 이를 비동기 처리를 하기 위해서 내부의 스레드풀을 별도 이용하여 처리한다.
이전 작업이 완료될 때까지 기다리면서 멈추지 않고, 다음 작업이 지연되지 않게 동작하는 패러다임이다. 오래 걸리는 작업은 백그라운드에서 진행하며, 완료 후에는 이벤트 루프를 통해서 task-queue를 거쳐 호출 스택에 올라오기를 기다린다.
CallBack Event Queue에서 하나씩 꺼내서 반복하는 동작을 의미한다. Event발생 시 호출 되는 함수들을 task-queue에 전달해서 담겨져 있는 콜백 함수들을 호출 스택에 넘겨준다.
동시에 발생한다는 뜻으로 요청과 그 결과가 동시에 발생된다는 약속인데, 바로 요청 시 시간이 얼마나 걸리든지 요청한 자리에서 결과가 주어져야 한다.
동시에 발생하지 않는다는 뜻으로 요청과 결과가 동시에 발생하지 않는다는 약속이다.
변수 선언이 어디에 있든 상관없이 다른 코드보다 먼저 실행되는게 특징
console.log(ex); // undefined
var ex;
var는 ES6이전에 변수할당 문법이고, let과 const는 ES6문법으로 동힐하게 변수를 선언할 떄 사용이 된다. let과 const는 var와 다르게 재선언이 불가능하다.
var는 호이스팅으로 인해서 선언된 라인 이전에 var값을 사용할 수 있지만 let과 const는 그러지 못한다.
그 이유는 변수들을 해당 스코프 최상위로 올리는 과정에서(호이스팅)에서 var는 선언과 동시에 초기회가 되는데, let과 const는 초기화가 되지 않기 때문이다.
식별자(변수명, 함수명, 클래스명 등)의 유효범위를 뜻하며, 선언된 위치에 따라서 유효 범위가 달라진다. 전역에 선언된 변수는 전역 스코프, 지역에 선언된 변수는 지역 스코프를 갖게 된다.
전역 변수는 어디서든지 참조가 가능한 값이지만 지역 변수는 함수 내부를 발한다. 따라서 지역 변수는 자신의 지역 스코프와 그 하위 스코프에서 유효하다.
한 가지 주의할 점은 JS에서 모든 Code Block(if, for, while, try/catch 등) 이 지역 스코프를 만들고, 이 특성을 블록레벨 스코프라고 한다.
반면 var로 선언된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정한다. 이를 함수레벨 스코프라고 한다.
전역 변수로 인해 재할당이 되거나, 전역 스코프를 공유하기 때문에 어딘가에 동일한 이름이 있다면 예상치 못한 결과를 가져올 수 있다는 위험이 있다.
따라서 오로지 함수코드 블록만을 지역 스코프로 인정하는 var 대신에, 블록레벨 스코프를 지원하는 let, const를 사용하는 것이 좋다.
모든 코드 블록 내에서 선언된 변수는 코드 블록 내에서만 유효하고, 코드 블록 외부에서는 참조가 불가능하다. 즉, 코드 블록 내부에서 선언한 변수는 지역 번수다.
JS 비동기 처리에 사용되는 객체로, 싱글 스레드 기반인 JS는 기본적으로 동기식이지만 API 요청 시 응답값을 마냥 기다릴 수 없기 때문에 비동기 처리가 필요하다.
하지만 비동기 처리를 하게 되면, 의도치 않은 순서로 함수가 실행될 수 있어서 원하는 부분에서 동기 방식으로 변환을 해줘야한다.
첫번째 방식은 콜백함수로, 콜백함수는 함수안에서 또 다른 함수를 호출하는 것인데, 여러 함수를 순서대로 호출할 경우가 있을 경우 콜백 지옥을 경험할 수 있다.
숫자 n을 파라미터로 받아와서 다섯번에 걸쳐 1초마다 1씩 더해서 출력하는 작업을 setTimeout
으로 구현해보면 Promise는 성공할 수 있고, 실패할 수 있는데 성공 시 resolve 함수를 호출하고, 실패 시 reject 함수를 호출한다.
No 비동기 처리 시 Promise를 사용하는 사람은 대부분 없다. 하지만 비동기 처리는 순차적으로 처리하지 않는것이 특징인데, 경우에 따라서 비동기 처리를 사용하면서 이를 순차적으로 처리해줘야 할 때가 있다.
가장 최근의 나온 비동기 처리법으로 async/await이 있다. 기존에 callback이나 Promise의 단점을 해소하고자 만들었다.
callback이나 Promise의 경우에 단점은 꼬리에 꼬리를 무는 가독성이 좋지 않은 코드가 나올 수 있는데 흔히들 callback 지옥 then() 지옥이라고 부른다.
await을 통해서 Promise 반환 값을 가져올 수 있는데, async/await를 사용하기 위해서는 함수 앞에 async를 붙여야만 await을 사용할 수 있다.
Promise를 활용하면 .catch()
를 통해서 Error-Handling이 가능하지만, async/await은 따로 Error-Handling이 없기 때문에 try-catch()
를 통해서 Error-Handling이 가능하다.
그리고 코드가 길어지면 길어질수록 Promise는 then() 지옥의 가능성이 있지만, async/await를 활용하면 비동기 코드가 동기 코드처럼 읽히게 해줘서 코드 흐름을 이해하기 쉬우며, 가독성이 좋다.