일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- SCSS extend
- vue mixin
- netlify redirect
- 이벤트 수식어
- 리액트
- Vue
- postcss
- 폼 입력 바인딩
- 프로그래머스 프론트엔드 데브코스
- 리스트 렌더링
- vuex map
- SCSS forward
- flex
- 프로그래머스 데브코스
- SCSS use
- 고양이 사진 검색기
- 프로그래머스 K_Digital Training
- vue 지역 컴포넌트
- 프로그래머스 데브코스 프론트엔드
- KDT 프로그래머스
- Spacer
- SCSS import
- intersection opserver
- git 같은계정 다른 컴퓨터
- react next
- 다른컴퓨터에서 git사용
- 쌓임맥락
- nextjs사용법
- vue 이벤트 수신
- KDT 프로그래머스 데브코스 프론트엔드
- Today
- Total
혼자 적어보는 노트
[Javascript] async await에 대한 이해 본문
async와 await
async와 await을 사용하면 프라미스를 좀 더 편하게 사용 할 수 있다.
async를 함수앞에 붙이면 자동으로 프라미스로 반환된다.
async 함수
async는 function앞에 위치하며 해당 함수는 항상 프라미스를 반환한다.
async function loadData(){
return "Hey";
}
loadData().then(console.log);
위의 함수가 실행되면 result가 "hey"인 이행 프라미스가 반환된다.
async function loadData(){
return Promise.resolve("Hey");
}
loadData().then(console.log); // Hey
위와 같이 async에 프라미스를 반환하는 것도 가능합니다.
async가 붙은 함수는 프라미스를 반환하고 프라미스가 아닌 것은 프라미스로 감싸서 반환하는것이다.
await
javascript는 await을 만나면 프라미스가 처리(settled)될 때까지 기다리고 그 이후에 반환이 된다.
예를들어 1초 뒤에 실행되는 프라미스가 있고 그것을 await없이 반환을 시도해보자.
*await는 async함수안에서만 동작한다. 즉 async함수 바깥의 최상위 에서는 await를 사용할 수 없다.
async function example() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("success"), 1000)
});
let result = promise;
console.log(result); // Promise {<pending>}
}
example();
위의 코드를 보면 프라미스가 실행되기 전에 result로 promise값을 받아버려서
예상된 결과가 나오지 않는다.
await를 사용해보자.
async function example() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("success"), 1000)
});
let result = await promise; // 1초 뒤 "success" 출력
console.log(result);
}
example();
위와 같이 함수를 호출하고 await로 실행이 잠시 중단되었다가 프라미스가 처리되면 실행이 된다.
아래의 예시와 함께 promise로 작성된 코드를 async로 바꾸어보자
[ promise ]
function delay(ms){
return new Promise((resolve) => setTimeout(resolve, ms));
}
function firstLoad(){
return delay(1000).then(()=>'Jay');
}
function secondLoad(){
return delay(1000).then(()=>"Jin");
}
function nameLoad(){
return firstLoad().then(first=>{
return secondLoad().then(second=>{
return first + second;
})
})
}
nameLoad().then(console.log);
firstLoad 와 secondLoad에 await를 사용하여 각각 1초 뒤에 return값을 받고
그 값에 따라 이름이 합쳐진 결과를 얻기 위한 코드를 작성해보았다.
하지만 nameLoad부분에서 return이 복잡하게 되어있어 한번에 이해하기가 힘들어진다.
이부분을 해결하기 위해 async await를 사용해보자.
[ async await ]
function delay(ms){
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function firstLoad(){
await delay(1000);
return 'Jay';
}
async function secondLoad(){
await delay(1000);
return 'Jin';
}
async function nameLoad(){
const first = await firstLoad();
const second = await secondLoad();
return first + second;
}
nameLoad().then(console.log);
async와 await을 사용하여 보다 간결하게 코드를 구현해보았다.
await는 promise.then보다 좀더 가독성이 좋으며 사용하기도 편하다.
하지만 위 코드를 하면 fist와 second가 각각 1초씩 기다렸다가 출력되서
nameLoad()가 완료되기까지 총 2초의 시간이 소요된다.
first와 second는 데이터를 받아올 필요가 없고, 겹치는 데이터가 없는 상태인데
이것을 각자 받아올 수는 없을까?
await 병렬 처리
async function nameLoad(){
const firstPromise = firstLoad();
const secondPromise = secondLoad();
const first = await firstPromise;
const second = await secondPromise;
return first + second;
}
nameLoad().then(console.log);
await하지 않고 firstPromise와 secondPromise로 동시에 받아온다음
first와 second에 await를 적용하여 두 개가 완료되었을 때 바로 실행이 되게끔 병렬처리를 하면
nameLoad가 출력되는데에 1초만 소요된다.
promise 병렬처리 - Promise.all()
function loadAll(){
return Promise.all([firstLoad(), secondLoad()])
.then(name => name.join(''));
}
loadAll().then(console.log);
위와 같이 Promise.all을 사용하여 배열로 두 값을 담아준 후
두 값을 join()시켜주어 노출하는 방식이 있다. await보다 코드가 깔끔하다.
에러핸들링
await에서의 에러는 throw가 던진 에러를 잡을 때 처럼 try catch를 사용하여 처리할 수 있다.
[ try/catch ]
async function example() {
try{
let response = await fetch("http://???"); //찾을 수 없는 주소
let user = await response.json();
}catch(error){
// 에러 발생 시 여기서 표시 가능
console.log(error);
}
}
example();
try에서는 여러개의 구문을 작성할 수 있으며 response와 user의 에러가 catch에서 잡아서 처리한다.
[ .catch ]
async function example() {
let response = await fetch("http://???"); //찾을 수 없는 주소
let user = await response.json();
}
example().catch(alert);
try/catch를 사용하지 않고 해당 함수에 .catch를 사용하여 에러를 핸들링 할 수도 있다.
정리
- async함수는 항상 프라미스를 반환한다.
- await는 async함수 안에서만 동작한다.
- 프라미스 앞에 await를 붙이면 프라미스가 처리될 때 까지 기다려준다.
- async/await이 promise.then보다 문법적으로 편하긴 하지만 await는 async함수 밖에서 사용할 수 없기 때문에
then/catch를 추가하여 핸들링 해야 한다.
- 병렬처리를 하려면 promise.all이 좀 더 깔끔하다.
'Javascript' 카테고리의 다른 글
[Javascript] clientWidth, clientHeight / scrollWidth, scrollHeight / scrollTop , scrollLeft (0) | 2021.11.24 |
---|---|
[Javascript] offsetTop, offsetLeft / offsetParent / offsetWidth, offsetHeight (0) | 2021.11.24 |
[Javascript] Promise에 대한 이해 (0) | 2021.11.23 |
[Javascript] Callback에 대한 이해 (0) | 2021.11.22 |
[Javacscript] class에 대한 기본적인 이해 (0) | 2021.11.19 |