일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- app router
- 리터럴 타입
- 투포인터
- Cypress
- 이분 검색
- React
- webpack
- Promise
- RTK Query
- dfs
- CORS
- 타입 좁히기
- map
- recoil
- tailwind
- 무한 스크롤
- 태그된 유니온
- SSR
- Jest
- autosize
- ESlint
- CI/CD
- 공변성
- useAppDispatch
- 반공변성
- async/await
- 호이스팅
- 인터섹션
- 결정 알고리즘
- TS
Archives
- Today
- Total
짧은코딩
async/await, Promise로 바꾸기 본문
반응형
then, catch 반복하기 === try, catch 분리하기
Promise
- catch는 앞부분을 다 책임진다!
const p = new Promise(
// 여기부터
(resolve, reject) => {
console.log("제일 먼저");
setTimeout(() => {
a = 5;
console.log(a);
resolve(a);
}, 0);
}
// 여기까지 동기
);
console.log("딴짓");
p.then((result) => {
console.log("result", result);
})
.then(() => {
//여기서 에러나면
})
.then(() => {})
.then(() => {})
.catch(() => {
// 나머지 then 다 건너 뛰고 여기로 이동
})
.finally(() => {});
- catch는 앞의 전체에 대한 catch
-catch를 여러 개 사용
const p = new Promise(
// 여기부터
(resolve, reject) => {
console.log("제일 먼저");
setTimeout(() => {
a = 5;
console.log(a);
resolve(a);
}, 0);
}
// 여기까지 동기
);
console.log("딴짓");
p.then((result) => {
console.log("result", result);
})
.then(() => {
//여기서 에러나면
console.log(2);
})
.catch(() => {})
.then(() => {
return Promise.reject(1);
})
.catch(() => {
console.log("에러 처리");
})
.then(() => {
console.log("에러 처리 후");
})
.catch(() => {
})
.finally(() => {});
- then, catch 계속 반복해도 됨
- catch는 자신의 앞에서 에러가 발생하면 실행됨
- catch를 특정 then에 대한 에러 처리만 할 수 있도록 할 수 있다.
async/await
-분리 전
// setTimeout을 Promise로 만드는 법
function delayP(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
});
}
async function a() {
try {
await delayP(1000);
await delayP(1000);
await delayP(1000);
await delayP(1000);
} catch (error) {
console.error(error);
}
}
-분리 후
// setTimeout을 Promise로 만드는 법
function delayP(ms) {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms);
reject(err); // 에러나면 에러 처리
});
}
async function a() {
try {
await delayP(1000);
} catch (error) {
console.error(error);
}
try {
await delayP(1000);
await delayP(1000);
await delayP(1000);
} catch (error) {
console.error(error);
}
}
- 이렇게 try, catch로 분리하면 에러 처리를 따로 할 수 있다.
- 위에서 사용한 Promise에서 then, catch를 연달아서 사용한 것과 같은 의미이다.
대입 방식
Promise
-then의 Promise가 아닌 return 값
const p = new Promise(
// 여기부터
(resolve, reject) => {
console.log("제일 먼저");
setTimeout(() => {
a = 5;
console.log(a);
resolve(a);
}, 0);
}
// 여기까지 동기
);
console.log("딴짓");
p.then((result) => {
console.log("result", result);
return 1;
})
.then((result) => {
console.log(result); // 1
// 함수는 아무것도 안적으면 기본적으로 return undefined
})
.then((result) => {
console.log(result); // undefined
})
.catch(() => {})
.finally(() => {});
- p의 첫 번째 then에서 return 1을 하면, 다음 then의 result는 1이 됨
- 두 번째 then에서 return을 안 하면, 다음 then의 result는 undefined
- 함수는 아무것도 안 하면 기본적으로 return undefined;
-then의 Promise인 return 값
const p = new Promise(
// 여기부터
(resolve, reject) => {
console.log("제일 먼저");
setTimeout(() => {
a = 5;
console.log(a);
resolve(a);
}, 0);
}
// 여기까지 동기
);
console.log("딴짓");
p.then((result) => {
console.log("result", result);
return Promise.resolve(1);
})
.then((result) => {
// Promise를 return하면 Promise를 resolve한 값이 리턴됨
console.log(result);
// 함수는 아무것도 안적으로 기본적으로 return undefined
})
.then((result) => {
console.log(result); // undefined
})
.catch(() => {})
.finally(() => {});
- 만약 then에서 Promise를 return 하면, 다음 then에서는 Promise의 resolve()된 값이 리턴됨
async/await
async function a() {
const a = await 1;
const b = await Promise.resolve(1);
}
- aync/await에서도 그냥 값을 넘겨주면 a에 1이 들어가고, Promise를 넘겨주면 b에 Promise의 resolve() 값이 들어감
- await은 "왼쪽 <- 오른쪽"으로 진행됨
async/await을 Promise로 바꾸기
async/await
async function a() {
const a = await 1;
console.log("a", a);
console.log("hmm");
await null;
const b = await Promise.resolve(1);
console.log("b", b);
return b;
}
async/await 코드를 Promise로 바꾸기
Promise.resolve(1)
.then((a) => {
console.log("a", a);
console.log("hmm");
return null;
})
.then(() => {
return Promise.resolve(1);
})
.then((b) => {
console.log("b", b);
return b;
});
- await을 기준으로 바꿔야 한다.
- await를 then으로 생각하자, await은 "왼쪽 <- 오른쪽", promise에서는 "왼쪽 -> 오른쪽"
- await이 3개 있으니까, then도 3개가 나오게 된다.
- 맨 처음 const a = await 1;은 Promise가 아닌 값이라 Promise.resolve(1)로 해준다.
- Promise화를 시켜야 then을 붙일 수 있다.
- 만약 const a = axios.get();이면 Promise니까 그대로 axios.get()을 써주면 된다.
- 첫 번째 then
- await과 await 사이에 있는 console들을 다 넣어줬다.
- 그리고 다음 await은 null이니까 return null을 해준다.
- 두 번째 then
- 대입하는 게 없으니까 매개변수 부분이 없어도 된다.
- 다음 await이 Promise.resolve(1)이니까 return Promise.resolve(1)을 해준다.
- 마지막 then
- b를 받아주고, console.log('b', b)를 추가해 주면 된다.
- async/await에 return b가 있으니까 return b를 해주면 된다.
- 사실 async/await과 Promise는 1대1로 대응되는 관계가 아니다.
- 이 코드에서는 되지만, 만약 마지막 줄이 return a + b;이라면
- 마지막 then에서 스코프 체인에 의해 a에 접근하지 못하여 애매해진다.
- 이땐 첫 번째 then부터 마지막 then까지 a를 인자로 넘겨주면 해결할 수 있다.
바뀐 Promise를 분석해 보기
async function a() {
console.log("2");
const a = await 1;
console.log("4");
console.log("a", a);
console.log("hmm");
await null;
const b = await Promise.resolve(1);
console.log("b", b);
return a + b;
}
console.log("1");
a()
.then((result) => {
console.log(result);
})
.then((result2) => {
console.log(result2);
});
console.log("3");
-결과
-분석
- 우선 처음에 console.log("1") 실행
- a() 호출
- 함수 a에서도 동기인 부분이 존재한다.
- 첫 번째 await의 위에 부분까지는 동기 부분이다.
- 첫 번째 await 직전까지만 실행이 되고, 첫 번째 await에서부턴 다 비동기여서 백그라운드로 넘어간다.
- 함수 a의 동기 부분만 실행이 되면 a는 호출이 종료된다.
- 함수 a에서도 동기인 부분이 존재한다.
- console.log(3)까지 실행하면 호출 스택은 빈다.
- 비동기 실행을 위해 백그라운드로 넘어감
- 백그라운드에는 await, await, await, then, then이 순서대로 쌓여있음
- Promise가 아닌건 자동으로 Promise.resolve()가 붙여지고 Promise는 resolve() 되니까, 태스크 큐의 마이크로(m)로 하나씩 이동
- 위에서 하나씩 실행되면, 이벤트 루프가 호출 스택이 빈 것을 확인하고 태스크 큐의 마이크로(m)에 있는 함수를 호출 스택에 올림
- then((result)=>{})에서 result는 함수 a의 반환값인 2이고, console.log(2) 실행
- then((result2)=>{})에서 result2는 undefined라서 undefined 출력
- 호출 스택, 백그라운드, 태스크 큐가 다 비고 JS 실행 종료
-출처
https://www.youtube.com/watch?v=1DGAyl4kxhY&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=15
반응형
'JS > 인간 JS엔진' 카테고리의 다른 글
클로저 (1) | 2024.01.30 |
---|---|
await 연달아쓰면 Promise.allSettled를 생각해보자 (0) | 2024.01.29 |
Promise에도 동기는 있다! (0) | 2024.01.27 |
비동기는 동시가 아니다 (1) | 2024.01.27 |
Promise, async/await (2) | 2024.01.25 |
Comments