[Javascript] Promise, async, await

donghyeok·2023년 6월 18일

자바스크립트 비동기 처리와 콜백 함수

자바스크립트 비동기 처리

  • 비동기 처리의 가장 흔한 사례는 제이쿼리의 ajax이다.
  • 비동기 처리시의 유의할 점은 응답 결과에 대한 처리이다.
  • 아래 ajax 예시의 경우 비동기 동작을 고려하지 않아 undefined 데이터를 사용하게 된다.
function getData() {
	var tableData;
	$.get('https://domain.com/products/1', function(response) {
		tableData = response;
	});
	return tableData;
}

console.log(getData()); // undefined

콜백 함수를 사용해 비동기 처리 문제 해결

  • 앞서 예시에서 콜백 함수를 사용해 응답 데이터에 대한 처리를 추가해 줄 수 있다.
function getData(callbackFunc) {
	$.get('https://domain.com/products/1', function(response) {
		callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
	});
}

getData(function(tableData) {
	console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});

자바스크립트 Promise

Promise란?

  • 프로미스는 자바스크립트 비동기 처리에 사용되는 객체이다.
  • 프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다.
  • 앞선 콜백 함수 예시를 프로미스를 이용한 코드로 바꿔보면 아래와 같다.
  • 콜백 함수로 처리하던 구조에서 프로미스 API를 사용한 구조로 바꾸었다.
function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

Promise 3가지 상태

  • 프로미스는 생성되고 종료될 때까지 3가지 상태를 갖는다.

Pending(대기)

  • 비동기 처리 로직이 완료되지 않은 상태
  • new Promise()메서드를 호출하면 대기 상태로 초기화 된다.
  • 해당 메서드를 호출할때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve.reject이다.
new Promise(function(resolve, reject) {
  // ...
});

Fulfilled(완료)

  • 비동기 처리가 완료되어 프로미스가 결과값을 반환한 상태
  • 프로미스 콜백함수의 resolve를 실행하면 Fulfilled 상태가 된다.
  • 완료 상태가되면 .then()을 통해 처리 결과값을 받을 수 있다.
// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});

Rejected(실패)

  • 비동기 처리가 실패하거나 에러가 발생한 상태
  • 프로미스 콜백함수의 reject를 실행하면 Rejected 상태가 된다.
  • 실패 상태가되면 .catch()로 실패처리 결과값을 받을 수 있다.
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});

자바스크립트 async와 await

  • async와 await는 자바스크립트 비동기 처리패턴 중 가장 최근에 나온 문법이다.
  • 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 해준다.
  • 아래는 비동기 처리를 콜백함수와 async, await로 구현했을 때의 차이이다.
//콜백 함수로 사용하는 경우 
//user를 변수에 할당하는 것이 아닌 콜백 함수 내부에서 처리해야 한다.
function logName() {
  fetchUser('domain.com/users/1', function(user) {
    if (user.id === 1) {
      console.log(user.name);
    }
  });
}

//async, await 예시 
//일반적인 시퀀셜한 코드처럼 변수에 할당받고 변수를 사용할 수 있다. 
async function logName() {
  var user = await fetchUser('domain.com/users/1');
  if (user.id === 1) {
    console.log(user.name);
  }
}

async & await 사용법

async function 함수명() {
  await 비동기_처리_메서드_명();
}
  • 비동기 처리 코드를 포함한 함수명에 예약어 async를 붙여준다.
  • 함수 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 await를 붙여준다.
  • 이때, 비동기 처리 메서드는 프로미스 객체를 반환해야 한다.
  • 아래 코드처럼 프로미스 API의 .then 등을 사용하지 않아도 되어 편리하다.
function fetchItems() {
  return new Promise(function(resolve, reject) {
    var items = [1,2,3];
    resolve(items)
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems); // [1,2,3]
}

여러개의 비동기 처리 코드 다루기

  • async & await 문법은 여러개의 비동기 처리코드를 다룰 때 빛을 발한다.
  • 일반적인 시퀀셜한 코드처럼 단순 변수에 할당하여 쓸 수 있어서 가독성이 훨씬 좋아지고 기존 비동기 처리코드 방식으로 사고하지 않아도 된다.
async function logTodoTitle() {
  var user = await fetchUser();
  if (user.id === 1) {
    var todo = await fetchTodo();
    console.log(todo.title); // delectus aut autem
  }
}

예외 처리

  • 예외를 처리하는 방법은 java 문법과 비슷한 try catch 구문이다.
  • catch 구문은 네트워크 통신 오류 뿐 아니라 일반적인 오류까지 잡아낼 수 있어 편리하다.
async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); // delectus aut autem
    }
  } catch (error) {
    console.log(error);
  }
}

출처 : https://joshua1988.github.io/web-development/

0개의 댓글