[ 06.22 ] Promise / async, await

Achievement Goals

🍎 synchronous / asynchronous
🍎 Promise 사용 패턴을 이해할 수 있다.
-resolve, reject의 의미와, then, catch와의 관계를 이해할 수 있다.
-Promise에서 인자를 넘기는 방법을 이해할 수 있다.
-Promise의 세가지 상태를 이해할 수 있다.
-Promise.all 의 사용법을 이해할 수 있다.
🍎 async/await keyword에 대해 이해하고, 작동 원리를 이해할 수 있다.

1. 동기(synchronous) 비동기(asynchronous)

컴퓨터에서의 동기적 방식이란, 어떠한 동작이 끝날때까지 다음동작은 시작하지 못하고 대기상태에 있어야 한다.
대부분의 웹/앱 서버는 비동기적 방식을 따르는데, 어떠한 동작이 끝나지 않더라도 뒤에있는 동작은 알아서 시작을 하게 된다.

예를들어, 어떠한 영상을 시청할 때 로딩속도가 느려진다고 해서 다른 컴포넌트에 있는 것들을 클릭하지 못하는 것은 아니다. 동영상이 로딩중에 있어도 다른 영상을 클릭하거나, 다른 사이트로 갈 수 있는것. 이 모든것이 비동기적으로 움직이는 것이다.

2.Promise

자바스크립트 비동기 처리에 사용되는 객체라고 볼 수 있다.
사실 프로미스를 하기 전에, 콜백의 개념을 먼저 알아야 하는데
콜백은 그동안 함수에서 자주 다뤘던 개념이다. 계속적으로 다른 함수를 불러내는 콜백으로 비동기를 표현해도 되지만, 불러올 함수가 많아질 경우 가독성이 떨어지게 되며 "콜백지옥" 이라는 것을 경험할 지도 모른다.

promise 는 이 콜백지옥을 벗어나 좀 더 가독성 있게 만들어 준다.
함수의 비동기 처리를 위해서 사용하는 promise는 클래스처럼 new 키워드를 이용하여 생성한다.

new Promise((resolve,reject)=>{~~})

🤙🏼 resolve❤️.then / reject❤️.catch

만약 어떠한 데이터나 서버를 받아 올 때, 그 데이터가 올바르게 받아오면 resolve에 있는 동작이 실행되게 된다.
반대로 데이터 받는데 실패를 한다면 reject 에 있는 err 가 동작하게 될 것이다.
나는 머리가 나빠서 ,,
resolve - then 짝꿍, reject - catch 짝꿍 이렇게 외워버렸다.

🤙🏼 Promise의 세가지 상태

new Promise()로 프로미스를 생성하고 종료될 때까지 3가지 상태를 갖는다.

Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태


위의 그림은 resolve, reject 없이 Promise 를 사용한 예시다.
로직완료가 덜 된 처리가 되어 이라고 써있는 것을 볼 수 있다.

function myPromise(){
 return new Promise((resolve,reject)=>{
     setTimeout((
       resolve('👅')
     ),2000)
  })
}

resolve, reject 를 썼을 경우 status 는 fulfilled 로 나오며, 이 형태를 정상적인 형태라고 볼 수 있다.

사용예시

 function myPromise(str){
   return new Promise((resolve,reject)=>{
     setTimeout(() => {
        console.log(str)
        resolve()
     }, Math.floor(Math.random()*100)+1
    )
  })
}
  
  const resultFace = () =>{
  myPromise('👀')
  .then(()=>{myPromise('👃🏼')})
  .then(()=>{myPromise('👄')})
}

str 이라는 인자를 갖는 myPromise 함수를 생성했다.
이 함수안에 프로미스를 생성하여 시간이 랜덤인 ms 를 작성.

프로미스로 만들었으니 제대로 데이터를 받았을 시 동작하는 함수도 작성해줘야 한다.
resultFace 라는 ,, 뭔가 어감이 이상하지만ㅋㅋㅋ
여튼 이 함수안에 myPromise 함수를 가져오고 인자로 내가 넣고싶은 문자열을 작성하면 된다.


어때유 내얼굴? ㅋㅎㅋㅎ

하지만 콜백지옥을 벗어난 promise 도 함수가 많아져, 잘못 사용하면 프로미스 지옥을 맛볼 수 있다.
그때 Promise Chaining 을 시켜주면 보다 더 깔끔하게 볼 수 있다.

let result = [];
return prom1
.then(data => {
  result.push(JSON.parse(data))
  return prom2
})
.then(data =>{
  result.push(JSON.parse(data))
  return prom3;
})
.then(data =>{
  result.push(JSON.parse(data))
  return prom4;
})
.then(data =>{
  result.push(JSON.parse(data))
  return result;
})

🤙🏼 Promise.all

그래도 복잡해보인다고?
그럴땐 비동기 실행 할 함수를 인자로 모두 묶어주는, Promise.all 써보자!
Promise.all 은 배열형태의 인자, 순회 가능한 객체가 온다.
신기한 점은 (사실 나만 신기한듯.)

-출처 : 모두의 갓 mdn ,,
mdn 에서 Promise.all의 인자에 함수이름을 땅땅땅 넣고 마지막에 .then 을 넣어주어 기존에 있는 함수이름만 넣어주면 되는 줄 알았는데 인자 안에서도 then 을 쓸 수 있다!!

  const readAllUsers = () => {
  const prom1 = getDataFromFilePromise(user1Path);
  const prom2 = getDataFromFilePromise(user2Path);
  
  return Promise.all([
    prom1.then(data=>JSON.parse(data)),
    prom2.then(data=>JSON.parse(data))    
  ])
  .then((data)=>{
    return data;
  })
}
  
  또는 
  
  const readAllUsers = () => {
  const prom1 = getDataFromFilePromise(user1Path);
  const prom2 = getDataFromFilePromise(user2Path);
  
  return Promise.all([prom1,prom2])
  .then(([data1,data2])=>{
    return `[${data1},${data2}]`
  })
  .then((data)=>{
    return JSON.parse(data);
  })
}

단, promise.all 은 인자로 들어온 비동기 함수 중 하나라도 reject 되면 나머지도 다 실행하지 않는다.

3. async/await

hoxy ,, promise 도 눈에 안들어오신다고욧?
그렇다면 async 를 고려해봐도 좋다.
무조건 async 를 쓰는것이 좋은것은 아니라고 하나 아직 정확한 차이는 모르겠다. 더 공부해봐야지 ,,

형태

async function myAsync(){
return await 비동기함수명.then(~~)
}
또는
const myAsync = async () =>{
return await 비동기 함수명.then(~)
}

async 는 await 와 같이 쓰이는 한 세트로 보면 된다.

소올직ㅎ .. 졸립다.
이만 자러갈게요 휘리릭~

좋은 웹페이지 즐겨찾기