동기(Synchronous)와 비동기(Asynchronous)

ssini·2024년 12월 26일
0

동기 (Synchronous)

  • 코드가 순차적으로 실행되는 방식
  • 이전 작업이 끝날 때까지 다음 작업을 대기 시킴
  • 작업이 오래 걸리면 프로그램 전체가 멈춤(Blocking)

동기(Synchronous) 예시

import fs from 'fs';

console.log("파일 읽기 시작");

// 동기적으로 파일 읽기
const data = fs.readFileSync('./test.txt', 'utf8');
console.log("파일 내용:", data);

console.log("파일 읽기 끝");

// 출력 결과
파일 읽기 시작
파일 내용: (test.txt의 내용)
파일 읽기 끝

동기 실행 흐름

  1. 파일 읽기 시작 출력
  2. 파일 읽기가 완료될 때까지 대기
  3. 파일 내용 출력
  4. 파일 읽기 끝 출력

동기 실행의 장단점

  • 장점
    • 코드의 실행 순서가 예측 가능함
    • 디버깅이 쉬움
    • 에러 처리가 직관적
  • 단점
    • 성능 저하 (특히 I/O 작업에서)
    • 사용자 경험 저하
    • 리소스 활용도가 낮음

비동기 (Asynchronous)

  • 작업이 끝날 때까지 기다리지 않음
  • 다른 작업을 먼저 수행한 뒤, 작업 완료 시점에 콜백 함수나 Promise로 결과를 처리함

콜백 기반 비동기

import fs from 'fs';

console.log("파일 읽기 시작");

// 비동기적으로 파일 읽기 (콜백 방식)
fs.readFile('./test.txt', 'utf8' (err, data) => {
	if (err) {
		console.error("파일 읽기 실패:", err);
		return;
	}
	console.log("파일 내용:", data);
})

console.log("파일 읽기 끝");

Promise 기반 비동기

import { promises as fs } from 'fs';

console.log('파일 읽기 시작');

// 비동기적으로 파일 읽기 (Promise 방식)
fs.readFile('./test.txt', 'utf8')
  .then((data) => {
    console.log('파일 내용:', data);
  })
  .catch((err) => {
    console.error('파일 읽기 실패:', err);
  });

console.log('파일 읽기 끝');

async/await 기반 비동기

import { promises as fs } from 'fs';

console.log('파일 읽기 시작');

async function readFile() {
  try {
    const data = await fs.readFile('.test.txt', 'utf8');
    console.log('파일 내용:', data);
  } catch (err) {
    console.error('파일 읽기 실패:', err);
  }
}

readFile();

console.log('파일 읽기 끝');

비동기 실행 흐름

  1. 파일 읽기 시작 출력
  2. readFile 함수가 호출되고, 파일 읽기 작업이 비동기로 시작
  3. 바로 파일 읽기 끝 출력
  4. 파일 읽기가 완료되면, 파일 내용 출력

비동기 작업의 주요 사용 사례

  • AJAX 요청
  • 파일 시스템 작업
  • 데이터베이스 쿼리
  • 타이머 기반 작업
  • 이벤트 리스너

비동기 병렬 처리 예시

import { promises as fs } from 'fs';

async function readMultipleFiles() {
  console.log('여러 파일 읽기 시작');

  try {
    // Promise.all을 사용한 병렬 처리
    const [file1, file2] = await Promise.all([
      fs.readFile('./file1.txt', 'utf8'),
      fs.readFile('./file2.txt', 'utf8'),
    ]);

    console.log('file1 내용:', file1);
    console.log('file2 내용:', file2);
  } catch (err) {
    console.error('파일 읽기 실패:', err);
  }
}

readMultipleFiles();

비동기 방식 비교

기술장점단점사용 사례
콜백간단하게 비동기 작업을 구현할 수 있음코드 중첩(콜백 지옥), 가독성 떨어짐간단한 비동기 작업 (예: 이벤트 처리)
Promise콜백보다 가독성이 좋고, 체인 형태로 작업 관리 가능체인이 길어지면 복잡할 수 있음비동기 작업이 여러 단계로 이루어져 있을 때
async/awaitPromise의 장점을 그대로 가져오면서, 동기 코드처럼 작성 가능모든 비동기 작업을 기다리므로 병렬 실행이 필요하면 추가 작업 필요가독성이 중요하고, 비동기 작업이 많이 않을 때

동기 vs 비동기 비교

특징동기(Synchronous)비동기(Asynchronous)
작업 처리 방식순차적으로 실행 (Blocking)동시에 처리 가능 (Non-blocking)
효율성작업업이 오래 걸리면 전체가 멈춤작업이 오래 걸려도 다른 작업을 계속 진행
사용 사례간단한 작업, 오류가 없는 상황네트워크 요청, 파일 읽기, 데이터베이스

선택 기준

  • 동기 방식 선택

    • 작업이 즉시 완료되는 경우
    • 다음 작업이 이전 작업의 결과에 의존적인 경우
    • 작업의 순서가 중요한 경우
  • 비동기 방식 선택

    • I/O 작업이 많은 경우
    • 여러 작업을 동시에 처리해야 하는 경우
    • 사용자 인터페이스의 반응성이 중요한 경우

게시판 예시로 보는 비동기 처리 방식

콜백 기반 게시판

// posts.service.js
import mysql from 'mysql2';

export const getPosts = (callback) => {
  const query = 'SELECT * FROM posts ORDER BY created_at DESC';
  db.query(query, (err, posts) => {
    if (err) return callback(err);
    callback(null, posts);
  });
};

// 사용 예시
getPosts((err, posts) => {
  if (err) {
    console.error('조회 실패:', err);
    return;
  }
  console.log('게시글 목록:', posts);
});

Promise 기반 게시판

// posts.service.js
import { pool } from './database.js';

export const getPosts = () => {
  return pool
    .promise()
    .query('SELECT * FROM posts ORDER BY created_at DESC')
    .then(([posts]) => posts);
};

// 사용 예시
getPosts()
  .then((posts) => console.log('게시글 목록:', posts))
  .catch((err) => console.error('조회 실패:', err));

async/await 기반 게시판

// posts.service.js
import { pool } from './database.js';

export const getPosts = async () => {
  try {
    const [posts] = await pool
      .promise()
      .query('SELECT * FROM posts ORDER BY created_at DESC');
    return posts;
  } catch (err) {
    console.error('조회 실패:', err);
    throw err;
  }
};

// 사용 예시
async function fetchPosts() {
  try {
    const posts = await getPosts();
    console.log('게시글 목록:', posts);
  } catch (err) {
    console.error('에러:', err);
  }
}

0개의 댓글

관련 채용 정보