본문 바로가기
JavaScript

[ES8] async, await

by oncerun 2020. 7. 3.
반응형

-- 2022-01-16

최근 JS를 공부하면서  async의 await을 제대로 이해하기 위해선 Symbol, 이터러블, 이터레이터, 제너레이터의 개념이 필요하다고 느꼇다. 

 

공부 후 재정리 예정

 

 

--------------------------------------------------------------------------------------------------------

 

promise를 좀 더 간결하고 간편하고 동기적으로 실행하는 것처럼 만들어주는 아이입니다.

 

then으로 엮여있는 promise들은 코드가 난잡해질 수 있기에 좀 더 간단한 api로 async, await을 사용하면 

우리가 순차적으로 코드를 작성하는 것처럼 보이게 도와줍니다.

 

async & await

 

clear style of using promise

그렇다고 모든 promise를 async & await으로 변경해야 하는 것은 아닙니다.

상황에 따라서 promise를 유지해야 하는 경우와 변환해야 하는 경우가 존재합니다.

 

많은 경험을 토대로 선택해야 합니다.

 

1. async 

 

function fetchUser(){

  //do network request in 10 secs.....

  return 'sung';

}



const user = fetchUser();

console.log(user);

무언가 오래 걸리는 코드를 비동기적인 처리를 하지 않는다면 자바스크립트 엔진은 동기적으로 코드를 수행하기에 다음 코드가 실행되기까지 10초가 걸리게 됩니다.  그러한 10초는 사용자가 그대로 기다려야 하만 합니다.

 

따라서 이러한 비동기적인 처리를 하기 위해서 우리는 promise를 사용했습니다.

function fetchUser(){

  return new Promise((resolve, reject)  =>{
     //do network request in 10 secs.....
     return 'sung'; //값을 전달하기전까지 pending상태를 유지합니다.
     resolve('sung');
  });

}

const user = fetchUser();
user.then(console.log); - > 전달받는 파라미터가 한개일경우 생략가능합니다.

 

좀 더 간편하게 비동기를 작성해주는 방법이 존재합니다.

바로 함수 앞에 async라는 키워드를 붙여주면 resolve()를 사용하지 않아도 됩니다.

 

aysnc function fetchUser(){
	
  return new Promise((resolve, reject)  =>{
     //do network request in 10 secs.....
     return 'sung'; //값을 전달하기전까지 pending상태를 유지합니다.
  });

}

const user = fetchUser();
user.then(console.log); - > 전달받는 파라미터가 한개일경우 생략가능합니다.

async 키워드를 쓰면 자동적으로 resolve와 reject를 상황에 따라 반환합니다. 

 

 

 

 

2. await 

 

await은 aysnc라는 키워드가 붙은 함수에서만 사용할 수 있습니다.

 

 

 


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

await 사용한 후
async function getBanana(){
	await delay(3000);
    return 'banana';
 }
 
 await 사용하기 전
function getBanana(){
	
	return delay(3000)
    .then(()=>'banana');
	
 }

 

chaining을 하는 것보다 동기적으로  작성하는 await이 좀 더 코드가 간결해지는 것을 확인할 수 있습니다.

 

promise도 중첩을 너무 많이 하다 보면 콜백 지옥을 경험할 수 있습니다.

 

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

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

만약 awiat을 사용하지 않고 banana와 apple을 가져오는 함수를 작성해본다면

 

function getFruits(){

 return getApple().then(apple =>{

   return getBanana().then(banana =>`${apple} ${banana}`);

});

}

콜백 지옥입니다.

 

따라서 우리는 이렇게 작성하면 간단하게 만들 수 있습니다.

async function getFruits(){

	
	const apple = await.getApple();
    const banana = await.getBanana();
    
    return `${apple}${banana}`;

}

 

서로 연관되는 메서드가 아니기에 병렬 처리를 할 수 있습니다.

 

다음과 같은 코드로 변경할 수 있습니다.

 

const applePromise = getApple();

const bananaPromise = getBanana();

get()메서드는 실행되는 순간 Promise 객체를 만들기 때문에 먼저 만든다음 await을 실행하게된다면

병렬 처리가 가능합니다.



const apple = await applePromise;

const banana = await bananaPromise;

return `${apple}{banana}`;

 

즉 Promise를 만들자마자 코드가 병렬적으로 실행이 되므로 동시에 얻은 뒤 기다린다음 반환하게 됩니다.

병렬적이라면 유용한 Promise API를 이용하면 더러운 위의 코드를 보지 않아도 됩니다.

 

Promise.all();을 사용합니다.

 

return Promise.all( [ getApple() , getBanana() ] )

. then( fruits => fruits.join(' + ')

);

 

반환받은 Promise객체를 배열로 받아 반환합니다. 전부 값을 받을 때까지 기다리게 됩니다.

 

만약 배열에 전달된 promise 중 가장 먼저 값을 리턴하는 promise만 전달되게 됩니다.

Promise.race([getApple() , getBanana()]);

 

 

 

 

반응형

'JavaScript' 카테고리의 다른 글

Preparation before Using "Promise"  (2) 2021.10.12
인스턴스 생성  (0) 2021.08.02
[ES6] Promise  (0) 2020.07.02
생성자와 프로토타입  (0) 2020.05.28
JSON  (0) 2020.05.27

댓글