

나는 위의 그림을 보면서 어느정도 이해가 됐다.
보통 동기는 은행, 비동기는 카페로 예를 많이 들던데, 나도 다른 예가 생각이 나지 않아 해당 예를 기록해두겠다.
은행에 가면 순번표를 뽑고, 이전 대기자의 작업이 모두 끝나야 내 차례가 돌아온다.
예약시스템이란건 없기 때문에 내 앞에 갑자기 다른 이벤트가 생길 수도 없고, 나와 동시에 다른 사람의 업무를 봐주지도 않는다.
다음 이벤트를 동작하는 실행 순서가 확실한 것을 동기적 방식이라 부른다.
아메리카노 단체손님 30명과 아메리카노 한 잔씩 두 대기자가 있는다고 했을 때, 카페 직원은 ‘앞에 주문이 밀려서 죄송합니다' 라고 말하겠지만 어쨌든 단체손님 30명보다 내가 시킨 아메리카노 한 잔이 더 빨리 나올 것이다.
연속적으로 발생하는 이벤트를 담은 후 완료되는 순서대로 일을 처리하는 실행 순서가 확실하지 않은 것을 비동기적 방식이라 한다.
비동기적 방식을 처리하는 방법은 콜백 함수 사용, Promise, async/await가 있다고 하는데, 콜백 함수 사용은 이번 포스팅의 주제가 아니기 때문에 넘어가도록 하겠다.
Promise 예제이다let num = 1;
let promise1 = new Promise((resolve, reject) => {
if(num === 1){
resolve('success');
}else{
reject('fail');
}
});
promise1.then(data => {
console.log(data);
}).catch(error => {
console.log(error);
}).then(data => {
console.log('something new!');
});
위처럼 catch 뒤에 또 체이닝이 되기도 한다고 한다.
resolve 시 값은 then 으로 넘어가고, reject 시 catch 로 넘어간다.then 와 catch 뒤에 다시 then 을 체이닝 했으므로 reject 시 catch 가 실행되고, 그 다음 마지막 then 도 실행된다.Promise는 다음 중 하나의 상태를 가진다.다음은 Promise의 정적메서드를 간단한 MDN의 설명과 간단한 예제와 함께 살펴보겠다.
let num = 5;
let promise1 = Promise.resolve(3);
let promise2 = 42;
let promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
let promise4 = async (num)=>{
return num;
}
Promise.all([promise1, promise2, promise3, promise4(num)]).then((values) => {
console.log(values)
})
// [3, 42, 'foo', 5]
Promise.all 에 함수도 넣을 수 있었다!let num = 5;
let promise1 = Promise.resolve(3);
let promise2 = new Promise((resolve, reject) =>
setTimeout(reject, 100, 'foo'));
let promise3 = async (num)=>{
return num;
}
let promises = [promise1, promise2, promise3(num)]
Promise.allSettled(promises)
.then((results) => results.forEach((result) => console.log(result.status)));
// fulfilled
// rejected
// fulfilled
// result도 궁금해서 찍어보았습니다.
// { status: 'fulfilled', value: 3 }
// { status: 'rejected', reason: 'foo' }
// { status: 'fulfilled', value: 5 }
let promise1 = Promise.reject(0)
let promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
let promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3]
Promise.any(promises).then((value) => console.log(value));
// "quick"
let promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
let promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
let promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 50, "three");
})
Promise.race([promise1, promise2, promise3]).then((value) => {
console.log(value);
// promise1과 promise2가 resolve 됐지만 promise3이 더 빠르다.
});
// "three"
Promise.any 와 다른점이라면 거부한 프로미스의 사유도 그대로 사용한다는 점이 있겠다.async/await는 Promise 객체를 반환한다.
그렇기 때문에 Promise 객체에서 사용하는 then 을 사용할 수 있다.
let delay = (sec) => {
let promiseData = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(console.log(sec + "초에 실행"));
}, sec * 1000);
});
return promiseData;
};
let funcAsync1 = async () => {
delay(5);
return "async1";
}
funcAsync1().then(result => {
console.log(result);
});
// await 썼을 때
let funcAsync2 = async () => {
await delay(2);
return "async2";
}
funcAsync2().then(result => {
console.log(result);
});
// async1
// 2초에 실행
// async2
// 5초에 실행
async/await의 경우 예외처리는 try/catch문을 사용한다.
let func = async () => {
try{
await delay(3);
}catch(e){
console.log(e);
}
};
그동안 너무 있는 코드로만 꾸역꾸역 코딩했던 것 같다.
내가 짜고 있는 코드가 어떤 코드인지 궁금해할 만도 한데 그렇지 않았다는 것이 실망스럽다.
Promise.all 이랑 async/await 만 주구장창 썼지 다른 건 관심도 없었다.
이제는 조금 더 관심을 갖고 공부해서 더 나은 코드를 짤 수 있게 노력해야겠다.
https://studyingych.tistory.com/63
https://velog.io/@yejinh/비동기-파헤치기
https://www.youtube.com/watch?v=pLiz2LdhYJM&list=PLjQHn5jzATkvggyE5oT7qU6FnmOv4ceY-&index=3
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/race