(7) 동기 vs 비동기

2019. 4. 3. 10:55 JavaScript BackEnd/Node.js, Express

nodejs 는 싱글스레드로 동작하는 시스템이기 때문에 동기적 방식으로 프로그램 로직을 작성한다면 성능면에서 문제가 될것이다.

그 이유는 이러하다. 하나의 로직이 있다고 가정하자.

그런데, 그 로직을 동기적 방식으로 처리한다면 100분이 걸린다. 그 로직을 전부 처리할 때까지 마냥 기다리게 되면 비효율적인 프로그램이 될것이다. 

따라서 비동기적인 방식으로 로직을 작성해야하는 이유를 반드시 알아야 하고, 또한 콜백함수의 개념을 정확하게 인지하고 있어야 한다. 


nodejs에서 기본적으로 제공되는 FileSystem 모듈에 대하여 알아보자. 

const fs = require('fs'); 


동기화 방식과 비동기화 방식에 대해 알아보자. 


1. 동기화 방식

fs.readFileSync(file[,options])

var data = fs,readFileSync('data.txt',{encoding:'utf-8'});

파일을 읽어올 때 동기화 방식으로 data.txt 파일을 읽어서 data라는 변수에 담아주고 있음.


option으로 인코딩에 대해 지정할 수 있다. 

data.txt 파일을 utf-8방식으로 저장했으므로, 파일을 읽어올때도 인코딩옵션에 대하여 utf-8로 명시해줘야 한다.

{encoding:'utf-8'}



2. 비동기화 방식

fs.readFile(file[,options], callback)  << recommended

반면, 비동기화 방식의 경우에는 data.txt 파일을 전부 읽어올 때까지 기다려서 해당 data(data.txt 파일에 있는 내용)를 변수에 담아주는 것이 아닌, 함수를 먼저 반환(리턴) >> 다른 작업을 수행하고, fs.readFile(file[,options], callback)  함수는 다른 백그라운드 응용프로그램에게 이 작업의 책임을 전가한다. 이 후에 작업이 완료되면 콜백함수가 실행되면서 결과를 가져온다. 


===================================================================================

sync_and_async.js  파일을 분석해보자.


const fs = require('fs');

// Sync

console.log(1);

var data = fs.readFileSync('data.txt',{encoding:'utf-8'});

console.log(data);

// 작업 요청을 했을 때 그 요청의 결과값(리턴값)을 직접 받는 것. 

// 요청의 결과값이 리턴값과 동일하다. 

// 코드에서 보다시피 fs.readFileSync('data.txt',{encoding:'utf-8'}) 를 호출하여 결과값(리턴값)을 직접 받아 data변수에 담아주는 것을 볼 수 있다. 

// 동기화 방식의 경우에는 받을 data가 있으면 그 data를 다 받을 때까지 해당 함수를 벗어날 수 없다. 

// 동기 + 블로킹 : 결과가 처리되어 나올때까지 기다렸다가 리턴값으로 결과를 전달한다.



// Async

console.log(2);

fs.readFile('data.txt',{encoding:'utf-8'}, function(error, contents){     //contents는 data.txt 파일 안의 data를 읽어온 것을 의미한다.

console.log(3);

console.log(contents);

});

console.log(4);

// ​작업 요청을 했을 때 그 요청의 결과값을 간접적으로 받는 것. 

// 코드에서 보다시피 fs.readFile('data.txt',{encoding:'utf-8'}, function(err, contents){

// console.log(3);

// console.log(contents);

// })

// 를 호출하여 결과값을 직접 받아서 변수에 담아주는 것이 아니라 함수를 호출하고 해당 함수를 곧 바로 반환한다음에 console.log(4)를 곧바로 실행하고, readFile함수의 

// 일련의 작업을 마친 후에 콜백함수(익명함수로됨)안에 console.log(3) 과 console.log(contents)가 실행되어 결과를 전달해준다.

// ※ callback 함수란 

// (마치 자바 프로그래밍에서 return null;이더라도 메소드 내부는 전부 실행되는 것 생각해주기, 해당 함수를 사용하려고 빌렸다가 곧바로 반환하는것으로 이해하기, 

// ATM기에 카드를 넣었는데, 카드를 인식한 후 카드는 곧바로 반환, 

// 그다음에 일련의 process에 의해 응용프로그램이 인식한 후, ATM기 내부 다른 작업들을 수행하고 다 끝나면 결과를 전달한다.)

// 요청의 결과값이 리턴값과 다르다. 1.함수리턴 2.결과는 나중에 가져옴.

// 해당 요청작업은 별도의 쓰레드에서 실행하게 됨

// 어떤 비동기 입출력 함수를 호출하면 입출력 작업을 운영체제에 요청한 후 해당 함수는 곧바로 리턴한다.  

// 운영체제는 입출력 작업을 완료하면 특별한 방법을 통해 응용 프로그램에 이 사실을 알린다.  

// 따라서 비동기 입출력 방식을 사용하면 함수 호출 시점과 입출력 시작 시점은 일치하지만, 

// 입출력 완료 시점과 함수 리턴 시점은 일치하지 않는다

// 비동기 + 넌블로킹 : 작업 요청을 받아서 별도의 프로세서에서 진행하게 하고 바로 리턴한다.

// 결과는 별도의 작업 후 간접적으로 전달한다.



★ 동기 비동기 그림으로 이해하기 .




동기 방식                                                           비동기 방식



☆ 동기 비동기 이해 +++

http://blog.naver.com/success87pch/220723722826



출처: https://sourceflower.tistory.com/7?category=561762 [소스플로우]