본문 바로가기

문돌이 존버/Node.js 스터디

Node.js 동기와 비동기 차이 알아보기 feat. 생활코딩

반응형
본 글은 생활코딩의 Node.js 강의를 보고 정리한 것입니다.

Node.js에는 특별하고도 재밌는 특징이 있습니다. 바로 동기(synchronous)비동기(asynchronous)를 구분하여 사용할 수 있다는 것인데요.

동기와 비동기의 차이에 대해선 아래 그림이 가장 직관적일 것 같습니다.

<출처: 넥스트리>

동기란 "순서대로 처리한다" 라고 이해해도 되지만, 좀 더 정확하게 말하면 "이후의 요청에 대해서 업데이트된 상황을 유지하기 위함"입니다. 예를 들어, 은행 거래를 생각해볼 수 있습니다.

A의 잔고 30만원
1. A가 온라인몰에서 10만원 짜리 키보드 구매 -> 잔액 20만원
2. A가 친구에게 10만원 송금 -> 잔액 10만원
3. A가 배달 음식에 10만원 소비 -> 잔액 0원

위에서 3번의 경우 이미 키보드를 사고 친구에게 송금했기 때문에 잔액 10만원이 남은 "업데이트"된 상황을 유지해야 하겠죠. 이 과정이 순차적으로 이루어지고 그때마다 잔고가 업데이트되어야 A는 얼만큼의 배달 음식을 시켜먹을 수 있는지 판단할 수 있습니다.

반면, 비동기는 이전의 상황이 어떻게 결론이 나든 상관없이 동시에 요청을 처리하는 방식입니다. 이는 곧 작업 효율을 향상시킬 수 있겠지만 은행 거래와 같이 업데이트가 중요하게 여겨지는 작업의 경우 위험할 수 있습니다.

그럼 이 차이를 코딩 결과를 보며 눈으로 확인해보겠습니다.

syntax/sample.txt -> B 라는 문자열 한 개 존재

먼저 동기식 처리를 살펴보겠습니다. 이때 readFileSync() 메서드를 사용합니다.

// 동기식 처리
var fs = require('fs');

readFileSync
console.log('A');
var result = fs.readFileSync('syntax/sample.txt', 'utf8');
console.log(result);
console.log('C');

결과에서 알 수 있듯 console.log() 가 코드상에 위치한 순서대로 출력됩니다. 다음은 비동기식 처리를 살펴보겠습니다.

// 비동기식 처리
console.log('A');
// 특정 값을 return하지 않음
// 첫 번째는 error, 두 번째는 파일의 내용을 인자로 전달
fs.readFile('syntax/sample.txt', 'utf8', (err, result) => {
    console.log(result);
});
console.log('C');

동기식 처리와 달리 코드상에 위치한 순서와 상관없이 A -> C -> B 로 출력된 것을 확인할 수 있습니다. fs.readFile() 부분을 처리할 동안 그 아래에 위치한 console.log('C') 를 먼저 처리하고 출력한 것입니다.

아래는 생활코딩 버전입니다. function() 부분이 callback 함수 부분으로 console에 찍힐 데이터를 전달하고 실제로 출력하는 역할을 합니다.

// function을 세 번째 파라미터로 줘야 함
// readFile()을 실행한 후에 세 번째 파라미터로 준 function을 수행
console.log('A');
fs.readFile('syntax/sample.txt', 'utf8', function(err, result){
    console.log(result);
});
console.log('C');

callback이란 말 그대로 "다시 부른다"는 의미이며 이것이 곧 역할입니다. 즉 fs.readFile() 을 통해 Node.js는 해당 디렉토리의 파일을 읽게 됩니다. 이 동안 console.log('C') 가 수행되어 출력이 될 것이고, 이후 console.log(result) 라는 function() 동작을 수행하여 그 결과가 출력되는 것입니다.

아래 예시를 통해 자바스크립트의 함수에 대해 좀 더 알아보겠습니다.

function a() {
    console.log('A');
}
a();

자바스크립트는 함수를 값으로 취급을 해서 변수에 저장할 수도 있다고 합니다. 이는 파이썬에선 못보던 형태라 낯설면서도 흥미로웠습니다.

var a = function() {
    console.log('A');
}
a();

a라는 변수가 담고 있는 값인 function 함수를 실행할 수 있는 것입니다.

callback 함수를 직접적으로 사용해보면 아래와 같습니다.

var a = function() {
    console.log('A');
}

function slowfunc(callback) {
    callback();
}

slowfunc(a);

function 함수의 파라미터로 callback을 전달하고 이를 실행하도록 했습니다. 그리고 이 전체를 "slowfunc" 이라는 이름의 함수로 만들고, callback에 변수 a를 전달했습니다. 결론적으로 slowfunc 를 call하면 파라미터로 들어온 a, 즉 console.log('A') 를 실행하는 함수"값"이 전달되고, 이를 실행한 결과를 출력하게 되는 것입니다.

728x90
반응형