할머니의 콤퓨타 도전기
(JavaScript) async & await 본문
Promise
- javascript에서 제공하는 비동기를 간편하게 처리할 수 있도록 도와주는 object
- 정해진 장시간의 기능을 수행하고나서, 정상적으로 기능이 수행되어졌다면 성공의 메세지와 함께 처리된 결과값을 전달해줌
- 기능을 수행하다가 문제가 발생하면 에러를 전달
- 언제 데이터를 받아올 지는 모르겠지만 promsie object를 갖고있고 then이라는 콜백함수만 등록하면 준비되는대로 콜백함수 불러줄게!
async & await
- clear style of using promise
- promise를 조금 더 간결하고 동기적으로 실행되는 것 처럼 보이게 만들어줌
- promise 위에 조금 더 간편한 API 제공
- syntatic sugar: 기존에 존재하는 것 위에 또는 감싸서 간편한 API 제공
function fetchUser() {
// do network request in 10 secs..
return 'jiwon';
}
const user = fetchUser(); // 비동기적인 처리를 하지않으면 사용자의 데이터를 받아오는데 10초가 걸림
// 만약 뒤에서 웹페이지의 UI 표시 기능 수행 코드들은 끝나는 동안 웹페이지에 표시되지 않음
console.log(user);
상당한 시간이 소요되는 작업(데이터를 받아오거나 파일을 읽을 때)에 이처럼 비동기 처리를 해주지 않으면 해당 작업이 완료되는 동안 코드 뒷 부분이 수행되지 않는다. 따라서 웹페지지 UI 표시 기능을 수행하는 코드들이 있을 경우 작업이 완료되기 전까지 표시되지않는다.
function fetchUser() {
return new Promise((resolve, reject) => {
// do network request in 10 secs..
resolve('jiwon');
});
}
const user = fetchUser();
user.then(console.log);
따라서 promise를 이용해 이처럼 비동기처리를 해줄 수 있다. 이때 async를 이용하면 바로 promise로 만들어준다.
async
async function fetchUser() { // async 이용하면 바로 promise로 만들 수 있음
return 'jiwon';
}
const user = fetchUser();
user.then(console.log);
console.log(user); // Promise { <state>: "fulfilled", <value>: "jiwon" }
await
- async가 붙은 함수 안에서만 사용 가능
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000); // await을 쓰게되면 delay()가 끝날 때 까지 기다려줌
// throw 'error';
return '🍎';
}
async function getBanana() {
await delay(1000);
return '🍌';
}
function getBanana() { // 이처럼 chaining을 하는 것 보다 위처럼 동기적인 코드를 쓰는 것 처럼 만드는게 좋음
return delay(30000)
.then(() => '🍌');
}
function pickFruits() {
return getApple().then(apple => {
return getBanana().then(banana => `${apple} + ${banana}`
);
})
} // promise도 너무 중첩적으로 chaining을 하게되면 콜백지옥과 비슷한 문제점 발생
pickFruits().then(console.log);
이처럼 promise도 너무 중첩적으로 chaining을 하게 되면 콜백지옥과 비슷한 문제점이 발생한다. 따라서 async & await를 이용해 동기적인 코드처럼 작성하는게 좋다.
async function pickFruits() {
const apple = await getApple();
const banana = await getBanana(); // getApple()과 getBanana()를 순차적으로 진행하면 비효율적. 서로 연관되어있지 않음
return `${apple} + ${banana}`;
}
pickFruits().then(console.log);
getApple()과 getBanana()는 서로 연관되어있지않다. 따라서 이를 순차적으로 진행하면 총 2초가 걸리게 되므로 비효율적이다.
async function pickFruits() {
const applePromise = getApple();
const bananaPromise = getBanana();
const apple = await applePromise; // 동기화
const banana = await bananaPromise; // 1s만에 병렬적으로 수행가능
return `${apple} + ${banana}`;
} // 동시에 수행이 가능한 경우에는 이처럼 작성하지는 않음
pickFruits().then(console.log);
따라서 이와 같이 작성할 수 있다. promise는 만들어지는 순간 지정한 콜백함수가 바로 수행되기 때문에 병렬적으로 getApple()과 getBanana()를 실행하고 await를 이용해 동기화를 시켜준다. 따라서 1s만에 병렬적으로 수행이 가능하다. 하지만 보통 이런식으로 작성하지는 않고 Promise API 중 하나인 all()을 사용한다.
useful Promise APIs
- all()
- promise 배열을 전달하게되면 모든 promise들이 병렬적으로 수행
function pickAllFruits(){
return Promise.all([getApple(), getBanana()]) // all(): promise 배열을 전달하게되면 모든 promise들이 병렬적으로 수행
.then(fruits => fruits.join(' + '));
}
pickAllFruits().then(console.log);
- race()
- 배열에 전달된 promise 중에서 가장 먼저 값을 리턴하는 것만 전달되어짐
function pickOnlyOne(){
return Promise.race([getApple(), getBanana()]); // race(): 배열에 전달된 promise 중에서 가장 먼저 값을 리턴하는 것만 전달되어짐
}
pickOnlyOne().then(console.log);
'Web Front-end > Javascript' 카테고리의 다른 글
(JavaScript) classList (0) | 2021.05.12 |
---|---|
JavaScript 최신 문법 (ES6, ES11) (0) | 2021.05.05 |
(JavaScript) Promise (0) | 2021.05.05 |
(JavaScript) Callback (0) | 2021.05.05 |
(JavaScript) JSON (0) | 2021.05.05 |
Comments