Javascript 는 Single Thread 이다.
이벤트를 처리하는 call stack이 하나 뿐인 언어이기 때문에 여러가지 이벤트를 처리할 때에 동기적으로 처리하게 된다면 하나의 이벤트가 모두 처리될 때까지 기다렸다가 다른 업무를 수행하게 되는 현상이 발생한다.
그래서 JS는 즉시 처리하지 못하는 이벤트들을 Web API로 보내 콜스택이 비었을 때 먼저 처리된 이벤트들을 줄 세워 다시 이벤트 큐에 정렬시켜 놓는다
Web API로 들어오는 순서는 중요하지 않고, 어떤 이벤트가 먼저 처리되느냐가 중요하다. 즉 순서가 확실하지 않은 비동기 처리인 것이다.
하지만 비동기 처리 이벤트들의 순서가 중요해질 경우는 어떻게 해야할까?
이렇게 순차적으로 진행되어야 하는 비동기를 처리하는 3가지 방식이 있다.
JS에는 다음의 3가지 비동기 처리 방식이 있다.
1. 콜백 함수 사용
2. Promise
3. Promise를 활용한 async/await
어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수
// #1
console.log('1');
// #2
setTimeout(function() {
console.log('2');
}, 2000);
// #3
console.log('3');
이렇게 찍어보면
이렇게 출력된다고 생각할 수 있지만, 비동기 방식으로 실행되는 setTimeout()
에 의해 다음과 같은 순서로 출력된다.
대기(pending)
: 이행하거나 거부되지 않은 초기 상태
Settled
: 결과 값이 성공 혹은 실패로 반환된 상태
이행(fulfilled)
: 연산이 성공적으로 완료됨
거부(rejected)
: 연산이 실패함
new Promise(function(resolve, reject) {
// ...
});
let myFirstPromise = new Promise((resolve, reject) => {
setTimeout(function(){
// 성공 시 resolve 사용
resolve(`Minho`)
}, 3000);
});
// 성공 시 then 사용하여 결과 처리
myFirstPromise.then((successMessage) => {
console.log(`Hi! ` + successMessage);
});
let mySecondPromise = new Promise((resolve, reject) => {
setTimeout(function(){
// 성공 시 resolve 사용
reject(`No Way!`)
}, 3000);
});
// 성공 시 then 사용하여 결과 처리
mySecondPromise.catch((failMessage) => {
console.log(`OMG! ` + failMessage);
});
정리
다 이해할 순 없지만
resolve
와.then
은 성공했을 경우,
reject
와.catch
는 실패했을 경우 사용한다는 것만 잡고 넘어가자
function a() {
return new Promise({
// ...
});
}
function b() {
return new Promise({
// ...
});
}
function c() {
return new Promise({
// ...
});
}
myFirstPromise()
.then(a)
.then(b)
.then(c);
promise에서 then, catch로 성공 실패를 처리해준 것처럼 여기서도 처리해주어야 한다
async function hello() {
return 'HIHIHIHIHIHIHIHI';
}
async function callHello(){
try {
let gutentag = await hello();
console.log('Success!!!');
} catch (e) {
console.log('Failure!!!!!!!');
}
}
callHello();
# 'Success!!!'
async function hello() {
throw new Error('Fail~~~~');
}
async function callHello(){
try {
let gutentag = await hello();
console.log('Success!!!');
} catch (e) {
console.log(e.message);
}
}
callHello();
# 'Fail~~~~'
참고
https://www.daleseo.com/js-async-callback/
https://velog.io/@wkahd01/%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC
https://velog.io/@change/JavaScript-asyncawait%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C