728x90

복잡한 then chaining도 코드를 난잡하게 만들기 마련이다.

그래서 Promise를 좀 더 간결하고 간편하고 동기적으로 실행되는 것처럼 보이게 만들어주는 syntactic sugar로 async/await 을 사용한다

syntactic sugar란?
  • 사람이 이해 하고 표현하기 쉽게 디자인된 프로그래밍 언어 문법

  • 사람이 프로그래밍 언어를 sweeter하게 사용 할 수 있도록 도와주는 문법

  • 더욱 더 간결하고 명확하게 표현이 가능한 문법

// 비동기 처리를 하지 않은 경우
function fetchUser(){
	//do network request in 10 sec
    return 'asdf'
}

const user  = fetchUser();
console.log(user);

이 경우 javascript는 기본적으로 동기적으로 코드를 실행하기때문에

network작업이 promise가 아닌 경우라면 10초를 기다린 후 console log에 asdf를 띄우게 된다.

화면을 띄운다고 할때 이렇게 기다린 후 출력하는 것은 매우 비효율적이기에 우리는 그동안 Promise로 이러한 현상을 해결해 왔다.

 

// async
async function fetchUser(){
	//do network request in 10 sec
    return 'asdf'
}

const user  = fetchUser();
console.log(user);

async를 도입하였다. async를 사용하는 방법은  함수 앞에 async를 붙이면 끝이다.

이 경우 이 함수는 자동으로 Promise를 반환하는 함수가 된다.

 

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

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

async function getBanana(){
	await delay(3000);
    return 'banana';
}

/* then을 사용했다면
function getBanana(){
  delay(3000).then(()=>{
  	return 'banana';
  });
}
*/
	

 async가 Promise를 대신했다면 await는 then을 대신한다.

직관적으로 then을 썼을때보다 이해하기 편하다.

 

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

pickFruits().then(console.log);

Promise/then을 대신하여 async/await을 도입한 경우이다. 이 경우 총 6초를 기다린후 `apple + banana` 를 반환받게 된다.

하지만 getApple()과 getBanana()는 서로 독립적인 함수이므로 서로를 기다려 반환 받을때까지 6초씩이나 걸릴 필요가 없다. 이러한 문제를 어떻게 처리할 수 있을까 방법은 다음과 같다.

 

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

pickFruits.then(console.log);

이전 시간에 Promsie는 선언과 동시에 실행된다고 배웠다. 이러한 Promise의 특성을 이용하여

getApple()과 getBanana()를 일단 동시에 실행시킨후 ( await(then) 을 붙이지 않은 Promise이기 때문에 서로를 기다리지 않는다)

뒷 줄에 이 실행 시킨 함수들이 각각 return 값 반환 할때까지 기다린다.

그 이 후 성공적으로 3초만 기다린 후 `apple + banana`를 반환한다.

 

그렇다면 만약 이런 병렬적으로 처리해야할 함수가 많다면 각 함수마다 일일히 이런 방식으로 처리해줘야할까?

이 경우 Promise의 내재함수를 사용하면 쉽게 해결 할 수 있다.

 

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

pickAllFruits().then(console.log);

Promise.all은 병렬적으로 실행해도 되는 Promise 함수를 동시에 실행하여 모든 return값을 반환받을때까지 기다린 후 then을 실행한다.

만약 Promise 함수중 하나라도 error(reject)가 발생하면 다른 응답을 기다리지 않은채 catch 구문으로 가게된다.

만약 이것이 싫고 모든 값을 반환받을때까지 기다리고 싶다고 한다면 Promise.all 대신 Promise.allSettled를 사용하면된다. 

'Javascript' 카테고리의 다른 글

prototype  (0) 2021.02.14
var vs let (const)  (0) 2021.01.13
비동기 처리 - Promise  (0) 2020.12.20
동기/비동기 처리 - Callback, Callback 지옥  (0) 2020.12.20
ECMA Script 2020 (ES11)  (0) 2020.12.13

+ Recent posts