Blocking is when the execution of additional JavaScript in the Node.js process must wait until a non-JavaScript operation completes. - Nodejs.org
Node js 문서에 따르면, Blocking이란
non-JavaScript operation 을 수행 중일 때, 추가적인 JavaScript Execution 들은 실행되지 않고 기다려야만 한다는 뜻이다.
그럼 non-JavaScript operation은 무엇이 있을까?
그럼 다음 두 코드를 비교해보자.
// 1번
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
moreWork(); // will run after console.log
// 2번
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
if (err) throw err;
console.log(data);
});
moreWork(); // will run before console.log
위 차이를 더 자세히 이해하기 위해선 테스크큐, 콜백함수 개념이 필요한데 우선 해당 개념 없이 서술해보겠다.
자바스크립트는 싱글 스레드언어이다. 위 코드를 실행하는 작업자가 싱글. 한 명이라는 뜻이다.
그럼 1번의 코드를 다시 보자.
한 명의 작업자가 file.md
라는 파일을 읽어오고, 해당 작업을 마치면 그 다음 함수인 data 함수를 console
에 출력한 다음, moreWork()
를 실행한다.
2번 코드 경우,
본 문서 앞에서 말한 non-JavaScript operation 을 수행함에 있어서 뒤에 함수(callback function)을 붙여주었다.
이렇게 코드를 작성하게 되면, 1번과 마찬가지로 한 명의 작업자가 코드를 실행해오다
해당 non-JavaScript operation 는 우리의 자바스크립트 한 명의 작업자가 아닌 다른 스레드(커널 스레드)가 수행하게 된다.
그럼 해당 작업을 background에서 다른 작업자가 수행하기에 우리의 외로운 javascript single 작업자는 백그라운드에서 작업을 기다릴 필요 없이 아래에 moreWork, 다른 일들을 수행할 수 있게됩니다. 즉, block 되지 않는다는 소리임!!
non-JavaScript operation 을 다른 스레드가 수행하고 결과(data or error)가 return되면
뒤에 선언해주었던 함수, 즉 callback 함수는 Task Queue
에 들어가있다가 자바스크립트의 싱글스레드(혼자 작업자) 의 콜스택이 비게 되면 Task Queue
에서 콜스택에 다시 들어가서 자바스크립트의 싱글스레드가 해당 함수를 처리한다.
방금 위 세 줄을 이해하기 위해선 callstack
, task Queue
, callback
의 개념이 필요합니다!
즉 Non-Blocking은 Blocking과는 다르게 다음 javascript의 실행이 이전 exection들에 의해 block되지 않는 것을 말한다.
// 에러가 발생
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
if (err) throw err;
console.log(data);
});
fs.unlinkSync('/file.md'); // 다른 background 작업자(thread)가 파일을 읽고 있는데
// 올바른 코드
const fs = require('fs');
fs.readFile('/file.md', (readFileErr, data) => {
if (readFileErr) throw readFileErr;
console.log(data);
fs.unlink('/file.md', (unlinkErr) => {
if (unlinkErr) throw unlinkErr;
});
});
위의 에러가 발생하는 코드는, backgrond에서 file을 read하고 있는데 그 이후의 실행, 즉 file을 unlink하는 함수가 non-block으로 실행이 되어버려 에러가 발생한다.
따라서 file을 unlink하는 것은 file read가 background에서 실행이 완료되고 나서 처리가 되도록 callback 함수로 처리해주어야 한다.