DEVELOP
article thumbnail

01. 비동기 프로그래밍과 콜백

# 동기실행 

 : 하나의 작업이 끝난 후 다른 작업을 실행하는 방식 

  - readFileSync 함수

# 비동기실행 

  : 특정 작업이 완료되었을 때 실행할 콜백을 등록해두고 바로 다음 코드로 실행을 넘기는 방식 

  - 비동기 프로그래밍 Node.js 환경에서 권장됨 

  - readFile 함수 

# 비동기 프로그래밍 

  - 비동기 함수 사용  / EventEmitter 객체 사용 

# readFile 함수   - 비동기 함수 

  - fs.readFile(path[,options], callback)

   - path : 내용을 읽을 파일의 경로 (필수적 인자)

   - options : 파일의 내용을 읽을 때 적용할 옵션 ( 선택적 인자 : 대괄호 안)

   - callback : 파일의 내용을 다 읽었을 때 실행될 콜백 ( 필수적 인자)

const fs = require('fs');

console.log('Start');

fs.readFile('./new','utf8', (error, data) =>{
  console.log(data);
});

console.log('Finish');

# setTimeout 함수 

: 특정 밀리세컨드 초 후에 특정 코드를 실행하도록 하는 함수 

- delay 인자에 2147483647 (2^31 - 1) 보다 크거나, 1보다 작은 값을 주면 실제로는  delay 인자에 1이 실행됨 

setTimeout(()=>{
  console.log('Hello World!');
},1000);

02. Node.js에서의 비동기 실행  ( -> 메인 스레드에 큰 부하를 주면 안된다) 

# 프로세스 : 하나의 실행 흐름

# 스레드 : 프로세스 안에 있는 더 작은 단위의 실행 흐름 

# 실행 : 하드디스크나 SSD에 저장되어 있던 프로그램의 내용을 메모리에 올려서 CPU가 실행하도록 만드는 것 

 

▷ Node.js 내부에서의 비동기 실행 구현 방법 중 한 가지

- 메인스레드는 빠르게 처리할 수 있는 작업들을 집중해서 혼자 처리 

    -> ex) CPU로 하는 수치 계산 작업, 네트워크로 들어오는 클라이언트의 요청을 받아들이고 응답하는 작업 

- 파일 읽기와 같이 오래 걸리는 작업은 다른 스레드에 맡김 

 

# CPU intensive job 

 - 고화질의 이미지를 처리하거나, 복잡한 수식 처리를 할 때 CPU를 집중적으로 사용 

 - Node.js에서는 CPU 수치 계산 작업을 메인 스레드가 처리하기 때문에, Node.js의 성능을 극도로 저하시키는 원인 

 - Node.js 에는 적절x ( 다른 서버 프레임워크를 사용하는 게 좋음 ) 


03. 이벤트 - 비동기 프로그래밍을 하는 또다른 방법 

# 이벤트 

: 어떤 일이 발생했음을 알리는 신호 

- 하나의 이벤트에 대해 여러개의 콜백함수를 설정할 수 있다.

- 이벤트를 발생시키고 그 이벤트의 콜백을 발생시키는 연산은 하나의 EvenEmitter내에서만 이루어진다. 

 

# EventEmitter

: 특정 이벤트에 리스너 함수를 달아서, 이벤트가 발생했을 때 이를 캐치할 수 있도록 만들어진 api 

- 이벤트 기반 프로그래밍

-  이벤트를 발생시키는 모든 객체는 EvenEmitter의 인스턴스 

- 코어 모듈의 많은 객체들이 EvenEmitter의 객체 

 

# eventEmitter.on(eventName,listener) : 콜백 등록 

 : eventName 이라는 이벤트가 발생했을 때 listener 함수를 실행

- .addListener 함수와 용도가 같음 ( 보통 더 짧은 .on을 사용) 

 

# eventEmitter.emit(eventName) 

 : eventName 이라는 이벤트를 인위적으로 발생시킴 

- 이미 코어 모듈에 존재하는 EvenEmitter객체를 사용하는 경우가 많은데, 이때 이벤트를 발생시키는 것은 직접 발생시키는 것이 아니기 때문에 사용할 일이 많지 않음 

const EventEmitter = require('events');
const myEmitter = new EventEmitter();

myEmitter.on('test',()=>{
  console.log('Succes!');
}); 

myEmitter.emit('test');

# once 메소드 

: 이벤트 핸들러가 해당 이벤트에 대해서 딱 한번만 반응해서 실행되도록 하는 메소드

myEmitter.once('test',()=>{
  console.log('Succes!');
});

 

# listener 메소드 

: 특정 이벤트에 대한 이벤트 핸들러들을 출력해주는 메소드 

- 특정 이벤트에 어떤 이벤트 핸들러들이 설정되어 있는지 조회할 때 

 

console.log(myEmitter.listeners('test'));

 

# off 메소드 

: 이벤트 핸들러를 해제하는 메소드 

 

# 이벤트에 추가 정보 함께 전달하기 

 - 인자 여러개보다는 객체를 전달해 주는 것이 더 깔끔 

 

   -  인자 여러개 전달 

const EventEmitter = require('events');
const myEmitter = new EventEmitter();

myEmitter.on('test',(arg1,arg2,arg3,arg4)=>{
  console.log(arg1);
  console.log(arg2);
  console.log(arg3);
  console.log(arg4);
}); 


myEmitter.emit('test','apple','banana','pear');

    - 객체 하나 전달 

const EventEmitter = require('events');
const myEmitter = new EventEmitter();

const obj = {type : 'text', data : 'Hello Codeit', date : '2020-09-01'};

myEmitter.on('test',(info)=>{
  console.log(info);
}); 


myEmitter.emit('test',obj);


03. 비동기 함수의 콜백이 실행되는 원리(심화)

▷ 비동기 함수의 콜백이 실행되는 원리

  1. 하나의 스레드(메인스레드) 가 js 코드를 순서대로 실행
  2. 메인 스레드가 Even Loop라는 로직에서 각각의 콜백들에 대한 실행여부를 판단하고, Queue에 넣은 후, Queue에 담긴 콜백들을 실행

 

# Event Loop 

: 각종 콜백들의 실행 조건(특정 시간이 경과했는지 등)을 확인하고, 실제로 콜백을 실행하는 로직

- 특정 콜백의 실행 조건이 만족된 것을 확인하면 Queue에 콜백들을 삽입 

 

▽ 무한루프 때문에 종료될 수 없어서, Event Loop에서 콜백을 다루는 그다음 단계로 아예 넘어가지 못함 

const fs = require('fs');

console.log('Start!');

fs.readFile('./new', 'utf8', (err, data) => {
  console.log('test'); // 절대 실행되지 않음
});

while (true) { // 의미없는 while 문이 자바스크립트 실행의 종료를 막고 있음

}
profile

DEVELOP

@JUNGY00N