자바스크립트 - Promise, async/await

이한결·2023년 1월 30일
0

부트 캠프

목록 보기
33/98
post-thumbnail

1월 30일 여정 22일차이다.

만약 순차적으로 실행하고 싶은 함수를 만들고 싶으면 어떻게 해요?

나는 단순히 그냥 콜백함수 쓰면 되는거 아닌가? 라는 생각을 했다. 하지만 질문에서 요구하는 답이랑은 조금 달랐다.

오늘의 Today I Learned

problem

자바스크립트에서 어떤 기능을 순차적으로 실행하기란 쉽지가 않다. 그 기능을 위해 그동안 콜백을 써서 해결해왔던 문제를 다른 더 좋은 방법으로 바꾸고자 한다.

try

당연하게도 항해99와 인터넷을 검색했다. 또한 모든 지식을 동원해보았다.

solve

아래의 내용은 애플코딩을 바탕으로 작성되었습니다.

순차적으로 함수를 실행한다고 해서 자바스크립트에서 밑에와 같이 코드를 작성한다면 아마도 많이 애를 먹을 것이다.

function 첫째함수(){
  console.log(1)
}

function 둘째함수(){
  console.log(2)
}

첫째함수();
둘째함수();

자바스크립트 외에 다른 언어를 사용해서 작성한다면 저것이 맞다. 하지만 자바스크립트에서는 아니다.

내가 생각한 방식은 밑에와 같다.

function 첫째함수(콜백){
  console.log(1);
  콜백();
}

function 둘째함수(){
  console.log(2)
}

첫째함수(둘째함수);

바로 콜백함수를 실행시키는 것이다. 그럼이제 순차적인 진행이 완성된다. 왜냐하면 첫째함수가 실행이 되고 그리고 인자로 둘째함수를 받아서 파라미터로 둘째함수가 실행된다.

하지만 저렇게 하다보면 문제가 발생한다. 만약 10개를 순차적으로 진행해야된다고 가정했을 때는 어떻게 될까?

첫째함수(function(){
  둘째함수(function(){
    셋째함수(function(){
      ......
    });
  });
}):

보기만 해도 토가 나온다. 어디서 많이 보던것 아닌가? 이전에 우리는 콜백함수를 배울때 콜백 지옥이라는 것을 배웠다. 바로 콜백 지옥은 이렇게 순차적으로 무엇인가를 실행하기 위해서 코딩하다가 생긴 것이다.

다행히도 위의 콜백지옥을 더 보기 좋게 해주는 것이 있다. 바로 Promise라는 것이다.

일단 Promise라는 것의 형태를 보자.

첫째함수().then(function(){
   그 담에 실행할거
}).then(function(){
   그 담에 실행할거
});

이것이 Promise의 형태이다. 어떤가? 이전의 콜백 지옥보다 훨씬 깔끔하지 않은가?
그렇다면 Promise라는 것을 더 자세히 보자.

const 프로미스 = new Promise(function(성공, 실패){
  성공();
});

프로미스.then(function(){

}).catch(function(){

});

먼저 맨위에 new Promise라는 것을 통해서 프로미스 변수 안에 Promise를 만들어 주었다. 그 안에는 콜백 함수가 들어간다.
그 콜백함수 안에는 2가지 인자를 받는다. 하나는 resolve이고, 하나는 reject이다. 당연히 resolve는 성공했을때 일것이다. 그럼 자연스럽게 나머지는 실패가 된다.

그 밑에 코드를 보면 then() catch(~~~)라는 2개가 보인다. then은 성공하면 then안에를 실행시켜준다. catch는 실패하면 에러를 보여준다.

그럼 만약 Promise안에 1초 대기 후에 성공하는 코드를 실행하려면 어떻게 해야할까?

const 프로미스 = new Promise(function(성공, 실패){
  setTimeout(function(){
    성공();
  }, 1000);
});

프로미스.then(function(){
  console.log('1초 대기 성공했습니다')
}).catch(function(){
  console.log('실패했습니다')
});

이렇게 하면 1초가 지난후에 성공과 실패로 나누어 질 것이다. (물론 위에서는 실패()를 쓰지 않았다. 그래서 catch는 출력되지 않을 것이다.)

만약 위의 Promise가 어렵다? 그럼 걱정하지 않아도 된다. async/await가 있다. 생각말고 바로 코드부터 보자.

async function 더하기(){
  var 어려운연산 = new Promise((성공, 실패)=>{
    실패();
  });
  try {  var 결과 = await 어려운연산 }
  catch { 어려운연산 Promise가 실패할 경우 실행할 코드 }
}

async/await는 ES8문법이다. 또한 Promise와 똑같은 역할을 한다. 대신 더 쉽다.
async를 함수 앞에다 사용하면 Promise 오브젝트가 자동으로 생성된다. 그리고 어떤 연산에 있어서 await를 써줌으로써 '그 연산이 끝날때까지 기다려주세요.' 와 같다.

그러면 try에서는 그것을 시도해본다. 만약 시도한 결과가 성공하면 결과 변수에 담길 것이다.
실패한다면 catch에서 실패할 경우의 코드가 실행된다. Promise의 then과 catch가 async/await에서는 try와 catch로 바뀐거 밖에 없다.

knew

매우 중요하지만 헷갈려서는 안되는 몇가지가 있다.
Promise의 경우 성공과 실패 판정 전에는 'pending'이라고 나온다.
성공 했을 시에는 'resolved'가 콘솔에 나오며, 실패시에는 'rejected'가 나온다. 물론 성공상태를 실패나 대기로 돌릴수는 없다.

마지막으로 Promise는 동기를 비동기로 만들어주는 코드가 아니다. 전혀 비동기적 실행과는 상관이 없다. 단순히 콜백 지옥과 같은 것을 막고 이쁘게 코딩하기 위한 것이다. 꼭 기억해두자.

마지막으로

굉장히 글이 길다. 그렇지만 이전까지 모든 포스팅은 이 글을 위해서 존재하는게 아닌가 싶다.

profile
평범한 삶을 위하여

0개의 댓글