Nodejs Blocking / Non-Blocking

Matthew Woo·2021년 12월 28일
0

Javascript

목록 보기
1/3
post-thumbnail

Blocking 이란?

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은 무엇이 있을까?

  • reading or writing data to a file
  • making a network request
  • reading or persisting data to a database

그럼 다음 두 코드를 비교해보자.

// 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

즉 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 함수로 처리해주어야 한다.

profile
Code Everyday

0개의 댓글