비동기 처리를 하기 위해 콜백함수를 도입했으나, 반복되다보면 콜백지옥에 빠지는 것을 봤다. 그래서 나온 게 Promise 키워드! 라지만... 사실 콜백지옥이랑 별 다를 게 없어보인다. 사실 프로그래밍 햇병아리 수준이라 그렇게 보이는 것일지도 모르겠다. 머리 아파 죽겠어요~
promise 상태
new Promise: 대기
resolve: 정상적인 동작이 되었을 때
reject: 에러가 발생했을 때
Async와 await
이 친구는 비교적 최근에 등장한 문법. 그래서 그런가 promise보다 훨씬 쉬운 것 같다.
async는 함수 앞에 붙이는 것으로, 해당 함수는 항상 promise를 반환. (promise가 아닌 것은 promise로 감싸 반환)
await는 async가 있어야만 등장할 수 있다.
가장 직관적이고 이해하기 쉬워서 이것만 쓰고 싶지만... 마음대로 될 리가 없지. 이전 코드를 읽으려면 지식이 필요하니까... 열심히 합시다~
// Promise
// 콜백지옥에서 탈출시켜줄 키워드
const a = () => {
return new Promise(resolve=>{
setTimeout(()=>{
console.log(1);
resolve();
},1000)
});
}
const b = () => {
return new Promise(resolve=>{
setTimeout(()=>{
console.log(2);
resolve();
},1000)
});
}
const c = () => {
return new Promise(resolve=>{
setTimeout(()=>{
console.log(3);
resolve();
},1000)
});
}
const d = () => console.log(4);
// 또 콜백에 빠짐...
// a().then(() =>{
// b().then(() => {
// c()
// })
// })
// then메서드에서 promise를 반환하면 메서드 체이닝 형식으로 then 한 번 더 사용가능
a().then(() => b())
.then(()=> c())
.then(()=>{
console.log(4);
});
// Async Await
const wrap = async() => {
await a(); // 비동기함수를 기다림
b();
}
wrap();
// await를 쓰려면 async가 붙어 있는 함수에서만 사용가능
// await는 promise 인스턴스가 반환되는 곳에만 사용해야한다.
// Resolve, Reject and errorHandling
// errorHandling: 에러를 처리하는 것
// 일반적인 처리 방식
const delayAdd1 = (index, cb, errorCb) => {
setTimeout(() => {
if (index > 10) {
errorCb(`${index}는 10보다 클 수 없습니다.`);
return
}
console.log(index);
cb(index + 1);
},1000)
}
delayAdd1(10, res => console.log(res), err=>console.error(err));
// Promise 이용
// resolve: 정상적인 동작이 되었을 때 실행할 코드에 사용
// reject: 에러가 발생할 코드에 사용
const delayAdd2 = index => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (index > 10) {
reject(`${index}는 10보다 클 수 없습니다.`);
return
}
console.log(index);
resolve(index + 1);
},1000)
})
}
delayAdd2(13)
.then(res => {console.log(res)}) // 정상적이면 작동
.catch(err => console.error(err)) // 에러가 나면 작동
.finally(()=> console.log('done')); // finally는 항상 출력
// async, await에서는 try, catch로 사용가능
const wrap1 = async() => {
try {
const res = await delayAdd2(2);
console.log(res);
} catch (err) {
console.error(err);
} finally {
console.log('done');
}
}
wrap1();
// 반복문에서의 비동기코드 사용법
const numbers = [1,2,3,4,5,6,7,8,9,10,11,12];
numbers.forEach(async number => {
const index = await delayAdd2(number);
console.log(number, index);
}
) // 순서대로 안나올 수도 있음
const wrap2 = async() => {
for (const number of numbers) {
const index = await delayAdd2(number);
console.log(number, index);
}
} // 순서대로 나옴
// 비동기코드를 순서대로 나오게 해야한다면 forEach문을 쓰지 말고 for of 문을 사용해야한다.
// fetch(주소, 옵션)
// 네트워크를 통해 리소스의 요청(request) 및 응답(response)을 처리할 수 있음
// Promise 인스턴스를 반환
'JAVASCRIPT' 카테고리의 다른 글
[JavaScript] 이벤트 버블링/캡쳐링 (0) | 2023.04.22 |
---|---|
[JavaScript] 이벤트(Event, addEventListener) (0) | 2023.04.22 |
[JavaScript] 동기/비동기 (콜백) (0) | 2023.04.21 |
[JavaScript] JavaScript의 동작 원리 (0) | 2023.04.21 |
[JavaScript] Document Object Model (DOM) - 4 (0) | 2023.04.21 |