일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
Tags
- 호이스팅
- async/await
- 타입 좁히기
- TS
- 인터섹션
- React
- tailwind
- 공변성
- CORS
- map
- ESlint
- useAppDispatch
- 무한 스크롤
- 투포인터
- RTK Query
- Jest
- dfs
- recoil
- webpack
- 이분 검색
- 리터럴 타입
- app router
- 결정 알고리즘
- CI/CD
- 반공변성
- SSR
- autosize
- 태그된 유니온
- Promise
- Cypress
Archives
- Today
- Total
짧은코딩
Promise, async/await 본문
반응형
Promise
프로미스는 내용이 실행은 되었지만 결과를 아직 반환하지 않은 객체
=> 나중에 사용 가능
const condition = true;
const promise = new Promise(()=> {
// 이 if 문은 동기로 실행
if (condition){
resolve('성공');
} else {
reject('실패');
}
});
promise
.then((message) => {
console.log(message);
})
.catch((error) => {
console.error(error);
});
- new Promise() 안의 if 문은 동기로 실행
- 성공하든 실패하든 값을 promise에서 값을 가지고 있음
- then, catch에서 값을 원할 때 꺼낼 수 있다.
- callback과 다른 점으로는 코드를 분리할 수 있냐 없냐가 엄청난 차이
- 콜백 지옥도 막을 수 있음
비동기 callback과 promise 비교
(참고로 callback은 동기, 비동기 다 있음)
-비동기 callback
function callback() {}
setTimeout(callback, 3000)
- 가장 아쉬운 점이 callback 부분이 강제인 점
- 3초 뒤라는 조건이 달성되면 바로 실행 됨
-promise
const promise = new Promise(resolce, reject) => {
setTimeout(() => {
resolve)
}, 3000);
});
// 다른 코드 실행
// 다른 코드 실행
// 다른 코드 실행
promise.then(() => {
//지금 실행
});
- promise에 값을 담아 놓을 수 있음
- 다른 동작을 실행하다가 내가 원할 때 사용가능
콜백 지옥과 promise 지옥
-콜백 지옥
step1(function (value1) {
step2(function (value2) {
step3(function (value3) {
step4(function (value4) {
step5(function (value5) {
step6(function (value6) {
// Do something with value6
});
});
});
});
});
});
- callback를 사용하면 위 코드처럼 콜백 지옥이 발생
- 콜백 지옥의 가장 근본적인 문제점은 결괏값을 바로 받아야 한다는 점
-promise 지옥
step1
.then(() => {
//처리
})
.then(() => {
//처리
})
.then(() => {
//처리
})
.catch(() => {
//처리
})
- 콜백 지옥은 해결이 됨
- 하지만 then, catch 지옥이 생기게 됨
여러 Promise 해결법
-Promise.all
// promise 지옥
const promise1 = Promise.resolve('성공1');
const promise3 = Promise.resolve('성공2');
// 해결책1
Promise.all([promise1, promise2])
.then((result) => {
console.log(result); // ['성공1', '성공2']
})
.catch((error) => {
console.error(error);
});
- Promise.all을 사용하면 해결이 가능
- 하지만 하나라도 실패하면 다 catch로 감 => 성공한 결괏값들 다 날라감
- catch
- catch는 "Promise.all([promise1, promise2])"에 대한 catch가 아니다!
- "Promise.all([promise1, promise2]).then((result) =>...)"에 대한 catch이다.
- then에서 에러나는 것도 catch로 간다.
-Promise.allSettled
// 해결책1
Promise.allSettled([promise1, promise2])
.then((result) => {
console.log(result); // ['성공1', '성공2']
// 실패한 것만 필터링해서 다시 시도 가능
})
.catch((error) => {
console.error(error);
});
- 성공한 것과 실패한 것을 구분해 줌
- 즉, 실패한 것만 필터링해서 다시 시도 가능
async/await(Promise 지옥 해결)
async/await
-Promise 지옥인 코드
function findAndSaveUser(Users) {
Users.findOne({})
.then((user) => {
user.name = 'zero';
return user.save();
})
.then((user) => {
return Users.findOne({ gender: 'm' });
})
.then((user) => {
// 생략
})
.catch(err => {
console.error(err);
});
}
-async/await 코드
async function findAndSaveUser(Users) {
let user = await Users.findOne({});
user.name = 'zero';
user = await user.save();
user = await Users.findOne({ gender: 'm' });
// 생략
}
- then을 await으로 대체
- 결괏값들을 미리 받는 것
- let user = await Users.findOne({}); 그렇기에 이 부분은 "왼쪽 <- 오른쪽"으로 실행
- 결국 await이 나오면 "왼쪽 <- 오른쪽"으로 실행이라 생각하면 됨
- await을 사용하려면 async는 필수였지만, 요즘은 await만 써도 됨
-Top-Level await
// promise 코드
const promise = new Promise(...);
promise.then((result) => ...);
// await 코드
const result = await promise;
Top-Level await이란 방식이 나와서 이렇게 사용 가능
aysnc에서 return 한 값 받기
async funxtion main() {
const result = await promise;
return 'zerocho';
}
//then으로 받기
const name1 = main().then((name) => ...);
// await으로 받기
const name2 = await main();
- async에서 return한 값은 then 혹은 await으로 받아야 함
- async도 promise라서 이렇게 해야 한다.
에러 처리
async funxtion main() {
try {
const result = await promise;
return 'zerocho';
} catch (error) {
// 에러 처리
}
}
//then으로 받기
const name1 = main().then((name) => ...);
// await으로 받기
const name2 = await main();
- try/catch를 활용하여 에러 처리 필요
for await of
const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');
(async () => {
for await (promise of [promise1, promise2]) {
console.log(promise);
}
})();
- 앞에서 설명했듯이 await은 then임
- for 문을 통해 반복문을 돌리면 promise에 다 then이 붙어서 나옴
- 따라서 for await of는 promise들을 반복할 때 자주 쓰임
요약
- 항상 async/await을 사용하는게 좋은건 아니다
- 여러 promise들이 있을 땐, Promise.allSettled이 더 효율적
-출처
https://www.youtube.com/watch?v=NEaDPHNflGI&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=10
https://www.youtube.com/watch?v=0f-jNhnN0Qc&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=11
반응형
'JS > 인간 JS엔진' 카테고리의 다른 글
Promise에도 동기는 있다! (0) | 2024.01.27 |
---|---|
비동기는 동시가 아니다 (2) | 2024.01.27 |
블록 스코프와 매개변수 (0) | 2024.01.24 |
this를 분석할 수 없는 케이스 (0) | 2024.01.23 |
this(this는 호출 시 결정) (1) | 2024.01.23 |