promise 를 조금더 간결하게 사용하게 하고
동기적 실행처럼 보이게 해준다.
promise chain (then => then => then ..) 을 일반적인 동기적 코드를 작성하는 것처럼
간편하게 해준다.
1. async
promise 로 작성시
//1.1 promise
function fetchUser() {
return new Promise((resolve, reject) => {
resolve('홍길동');
});
}
const user = fetchUser();
user.then(console.log);
async를 이용하여 작성시
promise를 쓰지 않아도 promise를 리턴하고 비동기 실행한다.
//1.2 async - promise를 쓰지 않아도 promise 비동기 실행
async function fetchUser() {
return '홍길동';
}
const user = fetchUser();
user.then(console.log);
2. await
promise 를 반환하는 async 가 붙은 함수 안에서만 사용 가능
Axios API(promise 반환)에서 주로 사용
async 가 붙은 함수가 실행되고
resolve나 reject 되어서 새로운 Promise가 반환될 때까지 기다려준다.
예시)
딜레이 후 사과 반환 -> 딜레이 후 바나나 반환 -> 두 리턴값을 합쳐서 출력
이런 구조의 코드가 있다면
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000); //딜레이가 끝날 때까지 기다림
return 'apple';
}
async function getBanana() {
await delay(500);
return 'banana';
}
Promise만 사용할 경우 콜백 지옥이 연상되는 then 지옥이 펼쳐질 수 있다.
function pickFruit() {
return getApple()
.then(apple => {
return getBanana()
.then(banana => `${apple} + ${banana}`); //콜백지옥이 떠오른다.
})
}
pickFruit().then(console.log);
await를 사용할 경우
async function pickFruit() {
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`;
}
pickFruit().then(console.log);
코드가 훨씬 줄어든다.
3. Promise API
위의 코드는 병렬적으로 실행되지 않음
사과 (1초) -> 바나나 (1초) : 출력되는데 총 2초가 걸림
사과(1초)
바나나(1초) -> 1초 출력
와 같이 병렬적으로 실행하려면 promise를 변수에 담고 await 해서 기다려줌
async function pickFruit() {
//사과(1초)=> 바나나(1초) =>2초 걸림
//병렬적으로 실행하기 위해선 : 사과(1초)+바나나(1초)=> 1초
//1. promise 만들기
const applePromise = getApple(); //promise는 만들자마자 실행된다.
const bananaPromise = getBanana();
const apple = await applePromise; //딜레이를 기다려줌
const banana = await bananaPromise;
return `${apple} + ${banana}`;
}
pickFruit().then(console.log);
이럼 딱 1초 걸린다.
단점 : 코드가 더러움
1) all
promise 의 all이라는 api를 사용하면 한번에 값을 받아올 수 있다.
all : resolve 나 reject 되어서 값이 다 반환될때까지 기다려면서 반환값을 배열에 담아둔다.
//2. promise all api 활용하기
//배열로 한번에 결과를 받고 새로운 promise를 반환해준다.
function pickAllFruit() {
return Promise.all([getApple(), getBanana()])
.then(fruits => fruits.join(' + '));
}
pickAllFruit().then(console.log);
위의 코드처럼 promise를 await하는 것보단 깔끔하게 쓸 수 있다.
2) race
resolve 나 reject를 했을 때 가장 먼저 리턴되는 것만 새로운 promise를 반환시켜 전달해준다.
만약 바나나를 가져오는데 0.5초가 걸린다면
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000); //딜레이가 끝날 때까지 기다림
return 'apple';
}
async function getBanana() {
await delay(500);
return 'banana';
}
//가장 먼저 리턴되는 것만 전달하기
function pickOnlyOne() {
return Promise.race([getApple(), getBanana()]);
}
pickOnlyOne().then(console.log); //사과(1), 바나나(0.5) => 바나나
둘다 1초라면 getApple이 먼저 호출되므로 사과만 출력
참고한 글
'Web > HTML CSS JS' 카테고리의 다른 글
html - map, text, list, table (0) | 2020.10.21 |
---|---|
HTML - 블록 레벨 요소, 인라인 요소, a 태그 관련 (0) | 2020.10.19 |
Java Script - 비동기 프로그래밍 1 (callback, promise) (0) | 2020.09.25 |
Java Script - JSON (0) | 2020.09.25 |
JavaScript - array api (0) | 2020.09.25 |