async await 내용 변형하기 (마지막 부분 중요)

KHW·2021년 7월 18일
0

Javascript 지식쌓기

목록 보기
63/95

+a 내용

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

위의 해당내용은

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

이와같이 바꿔쓸 수 있다.

기존에 배운 코드 (좋은 코드)

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

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

async function pickFruits(){
  const a = await getApple();
  console.log(a)
  const b = await getBanana()
  console.log(b);
  return `${a} + ${b}`;
}

pickFruits().then(console.log)
console.log('!!')
  • 결과
!!					//바로
apple					//0.5초 뒤
banana					//1초 뒤
apple + banana				//1초 뒤

  • 설명 : pickFruits는 async로 비동기이므로 해당 내용들은 대기한 상태로 아래의 console.log('!!')가 먼저 실행되고
    pickFruits()는 await에 의해 getApple함수를 가져오고
    getApple비동기함수이므로 return 'apple'은 먼저 실행되지않고 그위의 await부분의 해당 delay함수에 의해 0.5초 진행 후 apple을 리턴한다.
    그후 a를 출력하고
    마찬가지로 banana도 리턴 한후 b를 출력하고
    pickFruits()를 then을 통해 출력한다.
  • 혼자 설명해보기
    1) pickFruits 실행해야겠지
    2) 내용보니까 getApple함수가 await으로 되어있네?
    3) getApple을 보니 async함수이고 await으로 delay함수가 되어있네?
    4) delay함수를 보니 new Promise를 사용했네?
    5) 즉, delay함수는 어떤 시간이 지난 후 return 'apple'을 진행해야겠네?
    6) 0.5초가 지났으니 getApple함수가 끝나고 a를 출력하겠네?
    7) 이를 같이 진행하면 다시 0.5초 후 (총 1초) b가 출력되겠네?
    8) 그리고 a+b가 리턴되고 console.log로 합쳐서 출력되겠네?
    9) 맨 마지막 console.log('!!')는 pickFruits가 시간이 걸리는 비동기니까 그 밖에 있으므로 가장 먼저 출력되겠네?

주의 사항

async를 통해 return한 것은 Promise일 수도 있지만 간단한 값일 수도 있다.

async function a(){
  return '100'
}; 
a().then(console.log)

async function a(){
  return new Promise((resolve)=>{resolve(100)})
}; 
a().then(console.log)

변형해보기 1

function delay(ms){
  return new Promise(resolve =>setTimeout(()=>{
    console.log('나올까?');
    resolve()
  },ms));
}

function getApple(){
  delay(500);
  return 'apple';
}
function getBanana(){
  delay(500);
  return 'banana';
}

async function pickFruits(){
  const a = await getApple();
  console.log(a)
  const b = await getBanana()
  console.log(b);
  return `${a} + ${b}`;
}

pickFruits().then(console.log)
console.log('!!')
  • 결과
!!
apple
banana
apple + banana				//1~4까지 바로 출력
나올까?					//0.5초뒤 출력
나올까?					//0.5초뒤 출력

  • 설명 : pickFruits는 비동기이므로 그 아래의 console.이 먼저 출력되고 그 후 getApple을 보면 해당 함수는 async 함수가 아니므로 기다리지 않고 delay함수는 동작시키고 apple을 리턴하고 이를 출력하고
    마찬가지로 getBananaasync 함수가 아니므로 기다리지 않고 delay함수는 동작시키고 banan를 리턴하고 출력한다.
    이 후 각각의 delay함수가 0.5초 뒤 안의 내용이 출력되는 것을 알 수 있다.

  • 혼자 설명해보기
    1) pickFruits가 실행되는데 await으로 getApple함수의 리턴값을 받네?
    2) 그런데 getApple은 async 함수는 아니므로 천천히 읽으니 delay라는 new Promise가 있긴한데 getApple은 async가 아니니 해당 기다리는 것을 async 안에는 순차적으로 기다리지 않고 먼저 'apple'을 리턴하지? 그리고 출력하지
    3) 마찬가지로 getBanana도 순차적으로 기다리지 않고 먼저 'banana'를 리턴하지? 그리고 출력하지
    4) 그것을 통해 then을 진행하여 console.log로 둘다 출력하지?
    5) console.log('!!')는 맨 먼저 출력되겠지?
    6) 0.5초 뒤 각각의 delay에 의해 나올까?가 출력되겠지?

사실 이 코드는 이해하려고 시도해본 코드라 좋은 코드는 아님


변형해보기 2

function delay(result,ms){
  return new Promise(resolve =>setTimeout(()=>{
    console.log('나올까?');
    resolve(result)
  },ms));
}

function getApple(){
  const re = delay('apple',500);
  console.log('나는 getApple이 async가 아니라 바로 나와')
  return re;
}
function getBanana(){
  const ree = delay('banana',500);
  console.log('나는 getBanana가 async가 아니라 getApple이 끝나면 바로 나와')
  return ree;
}

async function pickFruits(){
  const a = await getApple();
  console.log(a)
  const b = await getBanana()
  console.log(b);
  return `${a} + ${b}`;
}

pickFruits().then(console.log)
console.log('!!')
  • 결과
나는 getApple이 async가 아니라 바로 나와
!!						//바로출력
나올까?										
apple
나는 getBanana가 async가 아니라 getApple이 끝나면 바로 나와	//0.5초뒤 전부 출력
나올까?
banana
apple + banana			//1초뒤 전부 출력

변형해보기 3

function delay(result,ms){
  return new Promise(resolve =>setTimeout(()=>{
    console.log('나올까?');
    resolve(result)
  },ms));
}

function getApple(){
  const re = delay('apple',500);
  console.log('나는 getApple이 async가 아니라 바로 나와')
  return '나는 바로 출력';
}
function getBanana(){
  const ree = delay('banana',500);
  console.log('나는 getBanana가 async가 아니라 getApple이 끝나면 바로 나와')
  return '나도 바로 출력';
}

async function pickFruits(){
  const a = await getApple();
  console.log(a)
  const b = await getBanana()
  console.log(b);
  return `${a} + ${b}`;
}

pickFruits().then(console.log)
console.log('!!')
  • 결과
나는 getApple이 async가 아니라 바로 나와
!!
나는 바로 출력
나는 getBanana가 async가 아니라 getApple이 끝나면 바로 나와
나도 바로 출력
나는 바로 출력 + 나도 바로 출력			//바로 출력
나올까?						//0.5초뒤 출력
나올까?						//0.5초뒤 출력

코드가 개판난 코드

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

function getApple(){
  const result =  delay('apple',500)
  console.log('~~~~~~~~~apple')
  return result;
}
function getBanana(){
  const result =  delay('banana',500)
  console.log('~~~~~~~~~banana')
   return result;
}

async function pickFruits(){
  const a = await getApple();
  console.log(a)
  const b = await getBanana()
  console.log(b);
  return `${a} + ${b}`;
}

pickFruits().then(console.log)
console.log('!!')
  • 결과
~~~~~~~~~apple
!!				//바로
apple
~~~~~~~~~banana		//0.5초 뒤
banana
apple + banana		//1초 뒤 
  • !!보다 ~~~apple은 먼저 나오고 비동기밖에서의 !!가 먼저 나오고 내부에서 순차적으로 진행해야하는데 개판난 코드다.

이를 수정하려면

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

async function getApple(){
  const result = await  delay('apple',500)
  console.log('~~~~~~~~~apple')
  return result;
}
async function getBanana(){
  const result = await  delay('banana',500)
  console.log('~~~~~~~~~banana')
  return result;
}

async function pickFruits(){
  const a = await getApple();
  console.log(a)
  const b = await getBanana()
  console.log(b);
  return `${a} + ${b}`;
}

pickFruits().then(console.log)
console.log('!!')

이렇게 async await을 추가로 붙인다.
이를 통해 async 밖의 비동기 부분인 !!는 먼저 수행되고 apple부분이 0.5초뒤 순차적으로 수행되고 1초뒤 banan부분이 수행되고 합친 결과로 then을 통해 나오게 된다.

!!					//바로
~~~~~~~~~apple
apple				//0.5초 뒤
~~~~~~~~~banana
banana	
apple + banana		//1초 뒤

정리

  1. await을 통해 받은 것이 Promise 형태의 경우 해당 Promise가 진행이 완료된 후에 async함수안의 await의 다음 코드가 실행되어지고 (Promise에 영향을 받아 순차적 실행)
    만약 아닐경우 바로 await의 다음 코드가 실행된다. (Promise에 영향을 받지않는 순차적 실행)
  • 이는 변형해보기 2와 3을 통해 확인 할 수 있다.
  1. async await를 놓은 후 await의 실행 함수 대상도 async await를 하면 순차적인 진행처리가 가능하다. (기존코드)
  1. 비동기처리로 async안의 코드를 제외한 밖의 코드는 async 안의 코드를 기다리지않고 먼저 진행되어야한다.
    async안의 코드 내에서 await으로 순차적으로 진행되어야 하므로
    await으로 받아온 것은 비동기와 관련한 new Promise 형태의 resolvereject여야한다.
  1. async를 통해 리턴한 값은 Promise형태이다.

주의 할 점

async await의 혼동이 안되게
async 안의 await(await 함수)에는 new Promise와 같은 resolve를 리턴해야한다.
만약 await의 대상인 함수(await 함수)안에 또 여러 문장이 있을때는 비동기를 순차적으로 진행하기 위해 해당 함수를 async로 쓰고 await으로 다시 진행을 시킨다.

profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글