티스토리 뷰
728x90
동기(synchronous) 및 비동기(asynchronous)
동기 방식
- 하나의 요청이 처리되는 동안 다른 요청이 처리되지 못하며 요청이 완료되어야만 다음 처리가 가능한 방식. (ex. java)
비동기 방식
- 하나의 요청 처리가 완료되기 전에 제어권을 다음 요청으로 넘겨 Blocking 되지 않으며 다음 요청을 처리 하는 방식. (ex. nodejs)
NodeJS
- 비동기 IO를 지원하며 Single-Thread 기반으로 동작하는 서버.
- 클라이언트의 요청을 비동기로 처리하기 위하여 이벤트가 발생하며 Event Loop가 처리.
- Event Loop가 처리하는 동안 제어권은 다음 요청으로 넘어가고 처리가 완료되면 Callback을 호출하여 처리완료를 호출측에 알려준다.
- 올바른 사용 환경
- 각 단위 작업이 아주 짧은 시간 안에 처리된다면 Node.js의 고성능의 병렬 처리의 장점을 극대화 함.
- 올바른 비동기 프로그래밍 방식으로 개발을 진행해야함.
- 각 단위 작업이 아주 짧은 시간 안에 처리된다면 Node.js의 고성능의 병렬 처리의 장점을 극대화 함.
- 올바르지 못한 사용 환경
- CPU를 많이 사용하는 처리 작업이나 대용량 파일을 처리하는 작업.
- 동기 방식의 개발 진행.
- CPU를 많이 사용하는 처리 작업이나 대용량 파일을 처리하는 작업.
동기 방식 프로그래밍
자바와 같은 프로그래밍 방식으로 위에서 아래로 진행되어진다.
위에서 설명했다시피 nodejs는 single thread이므로 동기 방식으로 작성할 경우 nodejs의 이점은 없어지므로 주의해서 사용한다.
var fs = require('fs');
console.log('start');
var filenames = fs.readdirSync('.');
var i;
for (i = 0; i < filenames.length; i++) {
console.log(filenames[i]);
}
console.log('end');
// 실행 결과: start -> filenames -> end
비동기 방식 프로그래밍
콜백 방식
- 자바 스크립트에서 함수는 일급 객체이므로 파라미터로 넘길 수 있음.
- 일급 객체란?
- 변수나 데이터에 할당 가능.
- 객체의 인자로 넘길수 있음.
- 리턴값으로 사용 가능.
- 일급 객체란?
- 실행 결과를 보면 비동기로 수행되는것을 알수 있음.
- 위의 전달된 콜백 함수는 디렉토리를 모두 읽은 후 호출됨으로써 비동기 프로그래밍이 가능해짐.
let fs = require('fs');
console.log('start');
fs.readdir('.', (err, filenames) => {
if (err) {
console.error(err);
return;
}
for (let i = 0; i < filenames.length; i++) {
console.log(filenames[i]);
}
});
console.log('end');
// 실행 결과: start -> end -> filenames
Promise 방식
- 복잡한 처리에서는 위의 콜백 방식을 사용할 경우 콜백 헬 발생
- 비동기 작업을 콜백에 비해 쉽게 컨트롤 가능, 비교적 가독성이 좋음.
- 오류 처리를 가시적으로 대응할 수 있음.
const fs = require('fs');
function readDirPromise() {
return new Promise((resolve, reject) => {
fs.readdir('.', function (err, filenames) {
err ? reject(err) : resolve(filenames);
});
});
}
readDirPromise()
.then(function (filenames) {
console.log('filenames - ', filenames);
})
.catch(function (error) {
console.log('error - ', error);
});
Generator 방식
const fetch = require('node-fetch');
// 외부 api를 사용한다.
function getUser(generatorObject, username) {
fetch(`https://api.github.com/users/${username}`)
.then(res => res.json())
.then(user => {
// user 이름을 줄테니까 다음을 실행시켜!
generatorObject.next(user.name)
});
}
let main;
// 비동기 함수가 포함되어있는 메인함수
function* mainFunction() {
let user;
// getUser를 실행하고 멈춰있어!
user = yield getUser(main, 'jessie');
console.log('1user - ', user);
user = yield getUser(main, 'kevin');
console.log('2user - ', user);
user = yield getUser(main, 'albert');
console.log('3user - ', user);
}
// iterator 함수 반환
main = mainFunction();
// main 함수 실행
main.next();
async/await 방식
- async, await 는 ES8(ECMAScript2017)의 공식 스펙(링크)
- promise, generator보다 더욱 절차적(동기적)인 프로그래밍 방식으로 개발가능
(async () => {
try {
const filenames = await fs.readdir('.');
for (let i = 0; i < filenames.length; i++) {
console.log(filenames[i]);
}
} catch (e) { console.error(e); }
})();
이벤트 루프
출처
728x90
'개발 언어 > NodeJS' 카테고리의 다른 글
NodeJS - WebRTC (0) | 2020.02.28 |
---|---|
NodeJS - Socket IO (0) | 2020.02.28 |
자바스크립트 - 프로토타입 상속 (0) | 2019.12.03 |
자바스크립트 - ES6문법 (0) | 2019.07.27 |
자바스크립트 - 객체 (0) | 2019.07.27 |
댓글