3.6.1 동기 메서드와 비동기 메서드_ asynchronous / synchronous method in Node.JS

sunghoon·2025년 3월 17일
1

2.0 Glove Project

목록 보기
20/35
post-thumbnail

노드는 대부분의 비동기 방식으로 처리합니다. 아래는 비동기 방식의 파일 시스템 코드입니다.

const fs = require('fs');

console.log('시작');
fs.readFile('./readme2.txt', (err, data) => {
    if (err) {
        throw err;
    }
    console.log('1번', data.toString());
});

fs.readFile('./readme2.txt', (err, data) => {
    if (err) {
        throw err;
    }
    console.log('2번', data.toString());
});

fs.readFile('./readme2.txt', (err, data) => {
    if (err) {
        throw err;
    }
    console.log('3번', data.toString());
});
console.log('끝');

위 코드를 실행하면 실행할 때마다 순서가 다르게 출력됩니다.

> node async.js
시작
끝
1번 저를 여러 번 읽어보세요
3번 저를 여러 번 읽어보세요
2번 저를 여러 번 읽어보세요

비동기 메서드들은 백그라운드에 해당 파일을 읽으라고만 요청하고 다음 작업으로 넘어갑니다. 따라서 파일 읽기 요청만 세 번을 보내고 console.log(’끝’)을 찍습니다. 나중에 읽기가 완료되면 백그라운드가 다시 메인 스레드에 알립니다. 메인 스레드는 그제서야 등록된 콜백 함수를 실행합니다.

  • 백그라운드 파일 읽기 작업은 스레드풀(3.6.4)과 연결됩니다.
  • 용어 차이
    • 동기와 비동기: 백그라운드 작업 완료 확인 여부
    • 블로킹과 논 블로킹: 함수가 바로 return되는지 여부

readFileSync(), writeFileSync()

아래의 코드는 동기 처리하는 코드입니다.

const fs = require('fs');

console.log('시작');

let data = fs.readFileSync('./readme2.txt');
console.log('1번', data.toString());

data = fs.readFileSync('./readme2.txt');
console.log('2번', data.toString());

data = fs.readFileSync('./readme2.txt');
console.log('3번', data.toString());

console.log('끝');

readFileSync()는 콜백 함수를 넣는 대신 직접 return 값을 받아옵니다.

이러한 동기 처리는 이전 작업이 완료되어야 다음 작업을 진행하기 때문에 백그라운드 작업하는 동안 메인 스레드는 아무것도 하지 못하고 대기하는 성능 문제가 발생됩니다.

동기 메서드들은 이름 뒤에 sync가 붙습니다.

아래는 비동기로 순서대로 읽고 출력하고 싶다면 readFile의 콜백에 다음 readFile을 넣으면 됩니다. 중첩된 콜백은 가독성이 떨어지지만 구현에는 문제없습니다.

const fs = require('fs');

console.log('시작');
fs.readFile('./readme2.txt', (err, data) => {
    if(err) {
        throw err;        
    }
    console.log('1번', data.toString());
    fs.readFile('./readme2.txt', (err, data) => {
        if (err) {
            throw err;
        }
        console.log('2번', data.toString());
        fs.readFile('./readme2.txt', (err, data) => {
            if (err) {
                throw err;
            }
            console.log('3번', data.toString());
            console.log("끝");
        })
    });
});

결과

시작
1번 저를 여러 번 읽어보세요
2번 저를 여러 번 읽어보세요
3번 저를 여러 번 읽어보세요
끝

Promise나 async/await로 중첩되는 콜백의 문제를 줄일 수 있습니다.

const fs = require('fs').promises;

console.log('시작');
fs.readFile('./readme2.txt')
  .then((data) => {
    console.log('1번', data.toString());
    return fs.readFile('./readme2.txt');    
  })
  .then((data) => {
    console.log('2번', data.toString());
    return fs.readFile('./readme2.txt');
  })
  .then((data) => {
    console.log('3번', data.toString());
    console.log('끝');
  })
  .catch((err) => {
    console.error(err);
  });

결과는 위와 동일합니다.


reference

  
profile
프라다 신은 빈지노와 쿠페를 타는 꿈을 꿨다.

0개의 댓글