Node.js

thread_pool, 이벤트, error 처리하기

쿠와와 2020. 12. 13. 14:27

thread_pool

fs, crypto, zlib 모듈의 메서드를 실행할 때는 백그라운드에서 동시에 실행됨 ( Node는 4개까지 지원해줌 )

스레드풀이 동시에 처리해줌

밑의 코드를 실행해보면 4개씩 실행이 되는 것을 볼 수 있다. 하지만 자기 컴퓨터 사이즈에 맞게 늘려줄 수 있다.

-> UV_THREADPOOL_SIZE=8

window에서는 SET UV_THREADPOOL_SIZE=8

기억하자.

const crypto = require('crypto');

const pass = 'pass';
const salt = 'salt';
const start = Date.now();

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('1:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('2:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('3:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('4:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('5:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('6:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('7:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  console.log('8:', Date.now() - start);
});

 

이벤트 만들고 호출하기

events 모듈로 커스텀 이벤트를 만들 수 있음

 

스트림에 쓰였던 on(‘data’), on(‘end’) 등과 비교

 

on(이벤트명, 콜백): 이벤트 이름과 이벤트 발생 시의 콜백을 연결해줍니다. 이렇게 연결하는 동작을 이벤트 리스닝이라고 부릅니다. event2처럼 이벤트 하나에 이벤트 여러 개를 달아줄 수도 있습니다.

 

addListener(이벤트명, 콜백): on과 기능이 같습니다.

 

emit(이벤트명): 이벤트를 호출하는 메서드입니다. 이벤트 이름을 인자로 넣어주면 미리 등록해뒀던 이벤트 콜백이 실행됩니다.

 

once(이벤트명, 콜백): 한 번만 실행되는 이벤트입니다. myEvent.emit('event3')을 두 번 연속 호출했지만 콜백이 한 번만 실행됩니다.

 

removeAllListeners(이벤트명): 이벤트에 연결된 모든 이벤트 리스너를 제거합니다.event4가 호출되기 전에 리스너를 제거했으므로 event4콜백은 호출되지 않습니다.

 

removeListener(이벤트명, 리스너): 이벤트에 연결된 리스너를 하나씩 제거합니다. 역시event5콜백도 호출되지 않습니다.

 

off(이벤트명, 콜백): 노드 10 버전에서 추가된 메서드로, removeListener와 기능이 같습니다.

 

listenerCount(이벤트명): 현재 리스너가 몇 개 연결되어 있는지 확인합니다.

const EventEmitter = require('events');

const myEvent = new EventEmitter();
myEvent.addListener('event1', () => {
  console.log('이벤트 1');
});
myEvent.on('event2', () => {
  console.log('이벤트 2');
});
myEvent.on('event2', () => {
  console.log('이벤트 2 추가');
});
myEvent.once('event3', () => {
  console.log('이벤트 3');
}); // 한 번만 실행됨

myEvent.emit('event1'); // 이벤트 호출
myEvent.emit('event2'); // 이벤트 호출

myEvent.emit('event3');
myEvent.emit('event3'); // 실행 안 됨

myEvent.on('event4', () => {
  console.log('이벤트 4');
});
myEvent.removeAllListeners('event4');
myEvent.emit('event4'); // 실행 안 됨

const listener = () => {
  console.log('이벤트 5');
};
myEvent.on('event5', listener);
myEvent.removeListener('event5', listener);
myEvent.emit('event5'); // 실행 안 됨

console.log(myEvent.listenerCount('event2'));

예외 처리

예외(Exception): 처리하지 못한 에러

  노드 프로세스/스레드를 멈춤

  노드는 기본적으로 싱글 스레드라 스레드가 멈춘다는 것은 프로세스가 멈추는 것

  에러 처리는 필수

 

1. 기본적으로 try catch문으로 예외를 처리

2. 노드 비동기 메서드의 에러는 따로 처리하지 않아도 됨

3. 프로미스의 에러는 따로 처리하지 않아도 됨

// 방법 1 에러가 발생할 만한 곳을 try catch로 감쌈

setInterval(() => {
  console.log('시작');
  try {
    throw new Error('서버를 고장내주마!');
  } catch (err) {
    console.error(err);
  }
}, 1000);


// 방법 2 콜백 함수에서 에러 객체 제공
const fs = require('fs');

setInterval(() => {
  fs.unlink('./abcdefg.js', (err) => {
    if (err) {
      console.error(err);
    }
  });
}, 1000);

// 방법 3 프로미스의 에러는 따로 처리하지 않아도 됨
const fs = require('fs').promises;

setInterval(() => {
  fs.unlink('./abcdefg.js')
}, 1000);

 

예측 불가능한 에러 처리하기

최후의 수단으로 사용

  콜백 함수의 동작이 보장되지 않음

  따라서 복구 작업용으로 쓰는 것은 부적합

  에러 내용 기록 용으로만 쓰는 게 좋음  -> 모든 에러를 기록하는 것이라고만 생각하고 고치는게 좋음

process.on('uncaughtException', (err) => {
  console.error('예기치 못한 에러', err);
});

setInterval(() => {
  throw new Error('서버를 고장내주마!');
}, 1000);

setTimeout(() => {
  console.log('실행됩니다');
}, 2000);

 

프로세스 종료하기

윈도우

맥 / 리눅스

'Node.js' 카테고리의 다른 글

REST API와 라우팅  (0) 2020.12.14
서버와 클라이언트  (0) 2020.12.13
파일 폴더 읽기, 쓰기  (0) 2020.12.12
버퍼와 스트림  (0) 2020.12.12
파일 시스템 접근하기, 동기와 비동기 메서드  (0) 2020.12.11