비동기 프로그래밍 ( Asynchronous ) ?
JavaScript 는 단일 스레드에서 동작합니다. => 한번에 한가지 일만 할 수 있습니다. ‘그럼 안 좋은거 아니야?’라고 생각할 수 있지만 싱글 스레드는 멀티 스레드가 겪어야 하는 골치 아픈 문제들을 신경 쓰지 않아도 된다는 장점이 있다.
싱글스레드만으로 멀티스레드 부럽지 않은 부드러운 소프트웨어를 만들기 위해서는 대가를 치뤄야 한다. 그 대가가 바로 비동기적(asynchronous) 프로그래밍이다.
- 하나의 요청 처리가 완료되기 전에 제어권을 다음 요청으로 넘겨 Blocking 되지 않으며 다음 요청을 처리 하는 방식. (ex. nodejs)
방식
콜백 방식
- 자바 스크립트에서 함수는 일급 객체이므로 파라미터로 넘길 수 있음.
- 일급 객체란?
- 변수나 데이터에 할당 가능.
- 객체의 인자로 넘길수 있음.
- 리턴값으로 사용 가능.
- 일급 객체란?
- 실행 결과를 보면 비동기로 수행되는것을 알수 있음.
- 위의 전달된 콜백 함수는 디렉토리를 모두 읽은 후 호출됨으로써 비동기 프로그래밍이 가능해짐.
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); }
})();
이벤트 루프
https://namjackson.tistory.com/30
'소소한 개발 이야기' 카테고리의 다른 글
undefined와 null의 차이점이란 ? (0) | 2021.12.24 |
---|---|
AJAX란 무엇인가 ? (1) | 2021.03.03 |
OOP와 함수형 프로그래밍의 차이점 (0) | 2021.02.23 |
함수형 프로그래밍이란 ? functional programming? (0) | 2021.02.22 |
OOP ( 객체지향 프로그래밍) 이란 ? (1) | 2021.02.18 |