비동기 처리를 시작하지 3 - async await

지은·2021년 6월 29일
1

ES6

목록 보기
6/6
post-thumbnail

promise chaining을 더 간결하고 간편하게 만들어주는 async와 await api를 알아보자.

async

async란?
AsyncFunction 객체를 반환하는 하나의 비동기 함수를 정의한다. 암시적으로 promise를 사용해 결과를 반환하는 것이다.

function fetchUser() {
	//do network request in 10 secs...
    return "오복";
}
const user = fetchUser();
console.log(user);

이렇게 시간이 걸리는 작업을 하는 경우, js는 원래 동기 언어이기 때문에 저 작업이 끝나는 동안 다른 작업을 수행할 수 없다. 그래서 비동기 처리를 해야 하는데, 이걸 promise로 만든다면

function fetchUser() {
	//do network request in 10 secs...
    return new Promise((resolve, reject) => {
    	resolve("오보깅");
        });
}
const user = fetchUser();
user.then(console.log);
console.log(user);

이걸 async로 변경하면 어떨까?

async function fetchUser() {
	//do network request in 10 secs...
    return "오보깅";
}
const user = fetchUser();
user.then(console.log);
console.log(user);

function 앞에 async를 달아주면 자동으로 promise를 만들어준다니! 훨----씬 간결해진 것을 확인할 수 있다.

await

await란?
promise를 기다리기 위해 사용한다. async function 내에서만 사용이 가능하다.

배가 고프니까 바나나랑 사과를 따와보자.

function delay(ms) {
	return new Promise(resolve => setTimeout(resolve, ms));
    }

async function getApple() {
	await delay(3000);
    return "apple";
	}

async function getBanana() {
	await dealay(3000);
    return "banana";
	}

이렇게 3초를 기다리면(await) 바나나와 사과를 획득할 수 있다. 이걸 같이 따오는 함수를 만들어보자.

function pickFruits() {
	return getApple().then(apple => {
    	return getBanana().then(banana => `${apple} + ${banana}`);
        });
    }
    
pickFruits().then(console.log);

흡사 콜백 지옥을 연상케 한다... async와 await를 사용해 바꿔보자.

async function pickFruits() {
	const apple = await getApple();
    const banana = await getBanana();
    return `${apple} + ${banana}`;
    }

getApple(), getBanana()가 일을 끝낼 때까지 await 하고 둘이 같이 return 해 줘! 확실히 이전의 코드보다 직관적인 걸 확인할 수 있다.

근데 getApple도 getBanana도 3초씩 걸리면 3초 걸려 사과 받고 3초 걸려 바나나 받고... 비효율적이다. 이 두 과정이 연관되어있지 않기 때문에 기다리지 않게끔 바꿔주자.

async function pickFruits() {
	const applePromise = getApple();
    const bananaPromise = getBanana();
	const apple = await getApple();
    const banana = await getBanana();
    return `${apple} + ${banana}`;
    }

3초만에 바나나와 사과를 같이 따올 수 있게 됐다! 그렇지만 이것도 코드가 너무 난잡하지 않나? promise의 다른 api를 활용해보자.

await 병렬 처리

promise에 내장되어 있는 all() api를 사용해보자. all api는 promise 배열을 전달할 경우 모든 promise들이 병렬적으로 다 받을 때까지 모아주는 api다.

function pickAllFruits() {
	return Promise.all([getApple(), getBanana()]).then(fruits =>
    fruits.join(' + ')
    );
}
pickAllFruits().then(console.log);

getApple, getBanana라는 promise를 배열로 묶어서 얘네가 다 받아질 경우 fruits에 모아주는 것이다. 이때 배열을 묶어주는 join을 사용한다.

그 뒤 pickAllFruits이 성공적으로 수행한다면(then) console.log를 수행하게 하는 것이다.

한 가지 기능을 추가해보자. 바나나와 사과 중 먼저 딸 수 있는 선착순 과일 1개를 받아오고 싶다면?

function pickOnlyOne() {
	return Promise.race([getApple(), getBanana()])
}

pickOnlyOne().then(console.log);

race는 먼저 처리된 걸 가져오는 api다. 위의 코드는 바나나와 사과에 속도 차이가 없으나 속도 차이가 있는 경우 유용하게 사용이 가능하다.

profile
Today I Learn # 개인 기록용 velog

0개의 댓글