Javascript 비동기 처리를 위한 Promise와 async function

Promise?

Javascript에서 비동기 함수 로직을 처리한 이후의 결과를 얻기 위한 함수이다.

비동기함수인 javascript는 특정 코드의 연산이 끝나기 전에 다음 코드를 계속 실행하기 때문에 위에 위치한 코드가 완료된 이후의 결과를 그 아래 코드가 사용한다면 개발자의 의도와 다른 결과, 심하면 에러를 발생시킬 수 있다. Promise는 이러한 비동기 함수를 동기 함수처럼 값을 반환하도록 해준다.

parameter로 ‘excutor’라고 불리우는 함수를 받고, 이 함수는 resolve와 reject function을 전달받는다.

promise는

  • pending: 이행되거나 거부되지 않은 초기 상태
  • fulfilled: 연산이 성공적으로 완료된 상태
  • rejected: 연산이 실패한 상태

다음 세 가지 상태 중 하나의 상태를 가지며 연산이 성공적으로 완료되었을 때 resolve함수를 호출하고, 오류가 발생하면 reject함수를 호출한다.

excutor 함수의 연산 이후 resolve함수의 parameter로 넘겨주는 함수를 then을 통해 받을 수 있고, 실패 및 오류 발생시 catch를 통해 받을 수 있다.

let myFirstPromise = new Promise((resolve, reject) => {  setTimeout(() => {    const num = Math.floor((Math.random() * 10) + 1);    console.log("number is " + num);    resolve(num);  }, 250);});myFirstPromise.then(num => {  if(num % 2 === 0) {    console.log("Even!");  } else {    console.log("Odd...");  }});

MDN에 있는 기본 예제를 조금 변형하여 만든 promise의 사용예이다.

myFirstPromise라는 새 promise를 만들었고 excutor함수는 250ms이후 1 ~ 10 사이의 자연수를 랜덤으로 반환해준다. 이후 반환해준 값이 짝수일 경우 “Even!”을, 홀수면 “Odd…”를 출력해준다.

만약 단순하게 랜덤 변수를 일정 시간 뒤에 선언해주고 값의 홀수짝수를 판단하는

setTimeout(function(){  const num = Math.floor((Math.random() * 10) + 1);  console.log(“number is “ + num);}, 250);if(num % 2 === 0) {  console.log(“Success!”);} else {  console.log(“Fail…”);}

다음과 같은 코드를 작성했다면 setTimeout이 끝나기 전에 if안의 코드가 실행되어 num값을 읽어오지 못한다. Promise는 이처럼 resolve와 then을 통해 코드를 비동기적으로 처리할 수 있게 해준다.

Async & Await

promise의 동작을 더욱 간단하고 동기스럽게(then, catch로 줄줄이 잇지 않아도 된다!) 표현할 수 있도록 ES8(ES2017)에서는 Async functioin와 await표현식을 지원하고 있다.

await는 async function내부에서만 사용이 가능하고 await는 promise앞에 작성된다. await 키워드가 붙은 promise가 실행되면 async함수는 해당 promise가 종료될 때까지 실행을 멈추고 대기한다.

위의 예제를 async함수로 다음과 같이 작성할 수 있다.

let myFirstPromise = new Promise((resolve, reject) => {  setTimeout(function(){    const num = Math.floor((Math.random() * 10) + 1);    console.log(“number is “ + num);    resolve(num);  }, 250);});async function foo () {  const num = await myFirstPromise;  if(num % 2 === 0) {    console.log(“Even!”);  } else {    console.log(“Odd…”);  }}foo();

async함수인 foo는 myFirstPromise를 await시켰다. 따라서 myFirstPromise의 excutor함수가 실행되어 resolve될때까지 함수의 다음 코드를 실행하지 않고 대기한다. 그 결과 250ms를 대기한 이후 결과값인 num을 가지고 계속 로직을 수행한다.

woohyun

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store