본문 바로가기
필수 개발지식/JS

[Node.js] 콜백함수(Callback Function), 이벤트 루프(Event Loop) 쉬운개념 정리

by 코딩하는짱구 2023. 7. 19.
반응형

✅콜백함수(Callback Function)란?

정의 : 함수에 파라미터로 전달되는 함수

일반적으로 콜백함수는 비동기 작업의 완료 처리, 이벤트 처리 등에 많이 사용되는 패턴

 

콜백함수란 크게보면 단순히 다른 함수에 전달되어 나중에 호출 되는 함수를 의미한다. 

비동기 작업의 완료 처리뿐만 아니라, 동기 작업에서의 특정 이벤트처리, 에러처리, 반복작업에도 활용할 수 있다!

ex) 콜백함수를 사용하여 동기작업을 수행하는 예시

function processArray(array, callback) {
  for (let i = 0; i < array.length; i++) {
    const result = callback(array[i]);
    console.log(`결과: ${result}`);
  }
}

function square(number) {
  return number * number;
}

const numbers = [1, 2, 3, 4, 5];
processArray(numbers, square);

결과: 1
결과: 4
결과: 9
결과: 16
결과: 25

 

 

 

✅비동기작업에서 사용되는 콜백함수(Callback Function)

강연자가 JS를 정의할 때 다음과 같이 설명한다.

” 자바스크립트는 싱글 쓰레드 기반이며 논 블로킹 방식의 비동기적인 동시성 언어이며 콜 스택, 이벤트 루프와 콜백 큐 그리고 여러가지 다른 API들을 가지고 있다. ”

 

👉용도 : Js에서 비동기 작업을 순차적으로 실행하고 싶을 때 씀

👉원리 :  Node.js는 단일 스레드로 동작하는데, 이는 작업이 완료될 때 까지 기다리지 않고 다음 작업을 실행할 수 있다는 것을 의미. 이를 위해 비동기적인 방식을 채택하며, 콜백함수는 비동기 작업의 완료 시점을 알려주고 결과를 처리하는 역할을 한다.

 

예시)

1. SetTimeOut 3초 '후에' 실행하도록  

// 3초 후에 실행되는 콜백 함수
function callback() {
  console.log('타이머가 만료되었습니다!');
}

// 3초 후에 콜백 함수 실행
setTimeout(callback, 3000);

2. 파일을 읽는 비동기적인 작업 수행

파일을 읽은 후 -> 콜백함수 호출 -> 콜백함수는 읽은 데이터나 에러 정보를 처리  

const fs = require('fs');

fs.readFile('파일경로', 'utf8', function(err, data) {
  if (err) {
    console.error('파일을 읽는 중 에러 발생:', err);
    return;
  }
  
  console.log('파일 내용:', data);
});

 

 

👉특징 : 다른데서 만든 함수를 가져올 수도 있다, 함수명을 임의로 지정할 수 있다, 콜백함수가 필요한 함수에만 사용 가능

 

👉장점 : 코드의 효율성과 유지보수성을 높인다

👉단점 : 콜백함수만 사용하면 코드가 복잡해지고 콜백 지옥 (callback hell) 문제 발생

👉단점 보완 : Promise, async/await 패턴 사용

 

 

 

 

 

✅Promise, async/await 패턴

1. Promise(프로미스)

  • 비동기 작업을 처리하기 위한 자바스크립트의 내장 객체
  • 비동기 작업의 결과를 나타내는 객체
  • 성공하면 완료된 결과를, 실패한 경우 에러 정보를 제공
  • 대기(Pending), 이행(Fulfilled), 거부(Rejected) 세가지 상태를 가진다 
  • ex)
const fs = require('fs');

function readFilePromise(filename) {
  return new Promise((resolve, reject) => {
    fs.readFile(filename, 'utf8', (err, data) => {
      if (err) {
        reject(err); // 실패한 경우, 거부 상태로 전환
      } else {
        resolve(data); // 성공한 경우, 이행 상태로 전환
      }
    });
  });
}

// Promise 사용 예시
readFilePromise('file.txt')
  .then(data => {
    console.log('파일 내용:', data);
  })
  .catch(err => {
    console.error('에러 발생:', err);
  });

 

2. async / await 비동기 작업을 처리하는 데 사용되는 문법적인 구조

  • Promise를 기반으로 동작 -> await async를 사용하여 promise를 사용하는 것!
  • await 키워드는 Promise 를 기다리는 표현식 앞에 사용된다
  • await 키워드는 Promise 가 처리되고 결과를 반환할 때 까지 함수의 실행을 일시중단 
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('데이터');
    }, 2000);
  });
}

async function getData() {
  try {
    console.log('데이터를 가져오는 중...');
    const data = await fetchData();
    console.log('데이터 가져오기 완료:', data);
  } catch (error) {
    console.error('에러 발생:', error);
  }
}

getData();

 

Promise, async/await 을 사용하면 비동기작업을 순차적으로 처리할 수 있는 구문을 작성할 수 있고,  콜백함수를 사용하는 것 보다 직관적이고 구조화된 코드를 작성할 수 있다. 

 

 

https://ko.javascript.info/async-await

 

async와 await

 

ko.javascript.info

 

 

 

 

✅동기(Synchronous)와 비동기(Asynchronous)란?

👉작업의 진행과 결과 처리 방식의 차이

 

📃동기(Synchronous) : 순차적, 블로킹(Blocking)

  • 순차적으로 진행
  • 작업 A가 완료되기 전에는 작업 B가 실행되지 않는다
  • 작업 A의 결과가 반환되기전엔 다음 작업이 진행x
  • 단일 스레드 환경에서는 작업 A가 완료될 때까지 대기해야 한다
  • 전통적인 프로그래밍 방식으로 코드가 직관적이고 이해하기 쉽다

 

📃비동기(Asynchronous) : 동시적, 논블로킹(Non-blocking)

  • 여러작업을 동시에 처리, 중단된 작업을 기다리지 않고 다음 작업 실행
  • 작업 A의 결과를 기다리지 않고 작업 B를 실행
  • 작업 A의 결과가 필요한 경우 콜백함수, Promise, async/await 를 통해 결과 처리
  • I/O작업이나 네트워크 요청과 같은 시간이 걸리는 작업에서 주로 사용된다

 

 

 

 

 

✅단일스레드?

👉Node.js는 기본적으로 단일 스레드로 동작하지만 비동기 I/O작업을 통해 동시성을 확보함 

 

스레드(Thread) : 프로그램 내에서 실행되는 독립적인 실행 단위, 프로세스 내에서 작업을 동시에 처리하고 병렬로 실행한다. 

Node.js : 단일스레드, 즉 Node.js 프로세스에는 기본적으로 하나의 주 스레드만 있는 것을 의미, 주 스레드는 이벤트루프(Event Loop)라고 불리는 메커니즘을 통해 비동기 I/O작업을 처리하고, 작업이 완료되면 콜백함수를 실행한다. 

장점 : 많은 클라이언트 요청을 효율적으로 처리

 

📃멀티스레드 방식과 단일스레드(Non-blocking) 방식의 예시

1. 멀티스레드 방식:

  • 가게에 도착하여 물건을 주문한다
  • 인포직원은 주문을 받은 후 창고직원에게 물건을 요청한다
  • 창고직원은 다른 곳에서 물건을 찾아오고, 인포직원은 다른 주문을 처리한다
  • 창고직원이 물건을 찾아와서 인포직원에게 전달한다
  • 인포직원이 고객에게 물건을 전달한다

인포직원, 창고직원이 동시에 다른 작업을 수행하므로 동시에 여러 주문을 처리하고 물건을 기다리는 동안 다른 주문을 처리할 수 있다. 

 

2. 단일스레드(Non-blocking) 방식: 

  • 직원이 창고에 물건을 주문한다
  • 주문이 완료되면 배송을 기다리는 동안 다른 작업을 처리한다
  • 배송이 완료되면 물건을 수령한다

즉 하나의 스레드가 작업을 순차적으로 처리하지만 비동기적인 방식을 통해 동시성을 확보하는 것.

비동기 I/O 방식은 작업이 완료되기를 기다리지 않고 다음 작업을 실행하는 방식.

 

 

 

 

 

✅이벤트루프(Event Loop)란?

 

[CS] Database에서 정규화(Normalization)란?

✅정규화(Normalization)란? 관계형 데이터베이스의 설계에서 중복을 최소화하여 데이터를 구조화 하는 프로세스 정규화의 목표 : 테이블 간에 중복된 데이터를 허용하지 않는 것, 즉 무결성을 유지

veritas-crystal.tistory.com

👉 Node.js 에서의 Event Loop란 비동기 작업을 처리하고 이벤트 기반의 프로그래밍 모델을 가능하게하는 핵심 개념

👉 내부적인 메커니즘, 이벤트 발생 및 처리, 콜백함수 호출, 타이머관리 등의 작업을 조작

 

👉 동작방식

  • 이벤트처리 : 이벤트 발생 시 해당 이벤트를 처리하는 콜백 함수를 등록 ex)파일이 읽혔을때
  • 이벤트 큐 : 이벤트 발생 시 해당 이벤트와 관련된 콜백 함수는 이벤트 큐(queue)에 추가 ex)FIFO로 대기  
  • 이벤트 루프 : 이벤트 큐를 주시, 실행중 작업이 없으면 큐에 있는 첫번째 콜백함수를 가져와 실행
  • 타이머 관리 : setTimeout() 같이 타이머의 시간이 만료된 경우, 해당 콜백 함수를 이벤트 큐에 추가/실행 

 

callback queue : 콜백함수의 대기열 ex) err, console.log etc..

 

 

 

 

 

 

**쓰레드의 개념참고 

2023.07.05 - [스터디관련] - [CS] 쓰레드와 쓰레드 풀

 

[CS] 쓰레드와 쓰레드 풀

✅Summary 쓰레드 : 프로세스 내에서 실행되는 실행 단위 쓰레드 풀 : 쓰레드를 미리 생성해두어 작업처리에 사용되는 쓰레드를 제한된 개수만큼 정해놓고 작업 큐에 들어오는 작업들을 하나씩 쓰

veritas-crystal.tistory.com

 

반응형