hoon's bLog

Javascript 자바스크립트 코딩의 기술 9장 외부 데이터에 접근하라 (1) 본문

IT/Javascript

Javascript 자바스크립트 코딩의 기술 9장 외부 데이터에 접근하라 (1)

개발한기발자 2024. 3. 8. 15:27
반응형


9장 외부 데이터에 접근하라

이번 포스팅에서는 Promise라는 개념과 async/await에 대해서 알아볼 텐데,

개념적으로 부족한 부분이 많아 기본 개념과 설명이 많고,

예제 코드도 책이 아닌 내가 직접 코딩을 해서 설명을 풀어보겠다.

이번 장을 이해하기 위해서는 비동기 방식과 콜백함수가 선행되어야 한다.

(추후 비동기와 콜백함수에 대해서 포스팅 예정)

tip43. 프라미스를 이용해 비동기적으로 데이터를 가져오라

프라미스(Promise)

  • 자바스크립트 비동기 처리에 사용되는 객체로, 비동기 작업을 전달받아서 응답에 따라 두 가지 메서드 중 하나를 호출하는 객체이다.
    • 비동기 작업이 성공하거나 충족된 경우 then() 메서드에 결과를 넘겨준다.
    • 비동기 작업이 실패하거나 거부되는 경우에는 Promise가 catch() 메서드를 호출한다.
    • then()catch() 메서드에는 모두 함수를 인수로 전달한다.
    • 이때 두 메서드에 인수로 전달되는 함수에는 비동기 작업의 결과인 응답만이 인수로 전달된다.
  • Promise는 다음중 하나의 상태를 가진다.
    • 대기(pending): 이행하지도, 거부하지도 않은 초기 상태.
    • 이행(fulfilled): 연산이 성공적으로 완료됨.
    • 거부(rejected): 연산이 실패함.
    • 대기 중인 Promise는 값과 함께 이행할 수도, 거부될 수도 있다.
  • Promise는 두 개의 콜백함수 인수로 resolve()reject()를 전달받는다.
    • resolve()는 코드가 의도대로 동작했을 때 실행된다.(reject()는 반대)
    • resolve()가 호출되면 then() 메서드에 전달된 함수가 실행된다.
    • reject()가 호출되면 catch() 메서드에 전달된 함수가 실행된다.
    • Promise가 담긴 배열을 받아 모든 Promise가 종료되었을 때의 성공 또는 실패 결과를 반환하는 Promise.all이라는 메서드도 있다.
  • 아래 코드를 통해 Promise 형태를 알아보자
let testPromise = new Promise((resolve, reject) => {
  setTimeout(function () {
  
    const isSuccess = Math.random() < 0.5; // 무작위로 성공 또는 실패 결정
    
    if (isSuccess) {
      resolve("promise!");
    } else {
      reject("failed!");
    }
    
  }, 250);
});

testPromise.then((successMessage) => {
  console.log("Hello! " + successMessage);
}).catch((failureMessage) => {
  console.log("Oh no! " + failureMessage);
});
  • line 01 : testPromise라는 새로운 Promise 객체를 생성, resolve와 reject라는 두 개의 콜백 함수를 인자로 받아서, resolve는 비동기 작업의 성공을, reject는 실패를 나타낸다.
  • line 02 : isSuccess에서 랜덤으로 성공, 실패를 결정하고, 250ms 후에 성공하면 resolve 호출, 실패하면 reject가 호출되어 Promise 반환
  • line 15 : then과 catch 메서드의 반환 값은 새로운 프로미스로 서로 연결 가능

tip44. async/await로 함수를 명료하게 생성하라

앞에서 Promise를 사용해 봤지만, Promise 체인의 단점은 콜백지옥과 같은 문제를 일으킬 수 있고,

then() 체인을 길게 이어나가면 코드의 가독성이 떨어지고 에러가 어디서 일어났는지 보기 어렵다.

그래서 이를 개선하기 위해, 더 비동기를 더 편하게 사용하기 위해 async, await를 사용한다!

 

async 키워드를 이용해서 선언한 함수는 비동기적인 함수이고 Promise를 반환한다는 것을 의미한다.

반환 값이 Promise 생성함수가 아니어도 반환되는 값을 Promise 객체에 넣는다.

async function testAsync() {
	...
	return testPromiseData;
	// 위와 같은 결과
    // return Promise.resolve(testPromiseData) 
}
  • await는 async 함수 안에만 사용할 수 있는 특별한 문법으로, Promise를 반환하는 함수 앞에 await를 붙이면, 해당 Promise의 상태가 바뀔 때까지 기다린다.
  • Promise가 성공 상태 또는 실패 상태로 바뀌기 전까지는 다음 연산을 시작하지 않는다!!

async / await 기본 문법

async function 함수명() {
  await 비동기_처리_메서드명();
}

비동기 처리 메서드가 꼭! Promise 객체를 반환해야 await가 동작한다!!

async / await 예제

function returnItems() {
  return new Promise(function(resolve, reject) {
    let items = [1,2,3];
    resolve(items)
  });
}

async function logItems() {
  let resultItems = await returnItems();
  console.log(resultItems); // [1,2,3]
}
  • returnItems() 함수는 Promise 객체를 반환하는 함수
  • returnItems() 함수를 실행하면 Promise가 이행(fulfilled)되며, resolve로 인해 결과 값은 items 배열이 된다.
  • logItems() 함수를 실행하면 fetchItems() 함수의 결과 값인 items 배열이 resultItems 변수에 담기며 콘솔에는 [1,2,3]이 출력
  • await를 사용하지 않았다면 데이터를 받아온 시점에 콘솔을 출력할 수 있게 콜백 함수나 .then()등을 사용해야 하지만, async / await 덕에 비동기에 대한 사고를 하지 않아도 된다. 
async function testAsync() {
  const testData = await testObject.testExFunction({
    id : "Hello async/await",
    pw : "asyncawait12"
  });
  
  console.log(testData);
  return testData
}
  • testExFunction 메서드 앞에 await로 인해 testData(Promise 객체) 상태가 바뀐 이후에, console.log(testData) 실행
  • 즉, 비동기를 동기로 바꾸는 것이다.
  • await는 then()과 같은 역할을 하는데, 콜백 함수를 등록할 필요 없기 때문에 더 편리하고, 체이닝으로 인해 코드가 복잡해질 일도 없다.
  • 비동기 함수의 내부에서 await 키워드를 사용하면, 값이 반환될 때까지 함수의 실행을 중지시킬 수 있다.

Reference

 

728x90
반응형