Promise

Džeko.Log·2021년 4월 26일
0

Synchronous & Asynchronous

  • 동기(Synchronous) : 동시에 일어나는, 요청과 결과가 동시에 일어나는 약속, 작성된 순서대로 코드 실행
  • 비동기(Asynchronous) : 동시에 일어나지 않는, 요청과 결과가 동시에 일어나지 않는다는 약속

비동기 처리란?

자바스크립트의 비동기 처리란 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미

// #1
console.log('Hello');
// #2
setTimeout(function() {
	console.log('Bye');
}, 3000);
// #3
console.log('Hello Again');

// setTimeout()을 실행 (setTimeout함수는 비동기로 작동)
// console.log('Hello Again')으로 넘어감
// ‘Hello’, ‘Hello Again’를 먼저 출력하고 3초가 지나면 ‘Bye’가 출력

Promise

: 자바스크립트 비동기 처리에 사용되는 객체 (주로 서버에서 받아온 데이터를 화면에 표시할 때 사용, 콜백지옥을 피하기 위한 방법)
: 비동기 작업의 최종 완료 또는 실패를 나타내는 객체

Promise의 3가지 상태

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

Promise 구현

// promise는 resolve와 reject를 파라미터로 받아온다.
// resolve (성공할 경우)
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
});

myPromise.then(n => {
  console.log(n);
});
// resolve 를 호출 할 때 특정 값을 파라미터로 넣어주면,
// 이 값을 작업이 끝나고 나서 사용 할 수 있다. 
// 작업이 끝나고 나서 또 다른 작업을 해야 할 때에는 Promise 뒤에 .then(...) 을 붙여서 사용하면 된다.

.then() : Promise를 리턴하고 두 개의 콜백 함수를 인수로 받는다.
또한 then 메서드는 Promise를 리턴하기 때문에, 이어지는 then 호출들을 손쉽게 연결할 수 있다.

// reject (실패할 경우)
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error());
  }, 1000);
});

myPromise
  .then(n => {
    console.log(n);
  })
  .catch(error => {
    console.log(error);
  });
// 실패하는 상황에서는 reject 를 사용하고,
// .catch 를 통하여 실패했을시 수행 할 작업을 설정 할 수 있다.

.catch() : catch메서드는 promise 구성에서 오류 처리에 사용된다 (Promise 에러 처리는 가급적 catch를 사용할 것)

// Promise chaining 
// 프로미스의 또 다른 특징은 여러개의 프로미스를 연결하여 사용할 수 있다.
function increaseAndPrint(n) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const value = n + 1;
      if (value === 5) {
        const error = new Error();
        error.name = 'ValueIsFiveError';
        reject(error);
        return;
      }
      console.log(value);
      resolve(value);
    }, 1000);
  });
}

increaseAndPrint(0)
  .then(increaseAndPrint)
  .then(increaseAndPrint)
  .then(increaseAndPrint)
  .then(increaseAndPrint)
  .then(increaseAndPrint)
  .catch(e => {
    console.error(e);
  });
// 여러 개의 프로미스를 .then()으로 연결하여 처리

Promise.all

: 순회 가능한 객체에 주어진 모든 Promise가 이행한 후, 혹은 Promise가 주어지지 않았을 때 이행하는 Promise를 반환한다 (여러 프로미스의 결과를 집계할 때 유용하게 사용)

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const getDog = async () => {
  await sleep(1000);
  return '멍멍이';
};

const getRabbit = async () => {
  await sleep(500);
  return '토끼';
};
const getTurtle = async () => {
  await sleep(3000);
  return '거북이';
};

async function process() {
  const results = await Promise.all([getDog(), getRabbit(), getTurtle()]);
  console.log(results);
}

process();
// 등록한 프로미스 중 하나라도 실패하면, 모든게 실패 한 것으로 간주한다.

async & await

: 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법

async & await의 문법

// 함수 앞에 async, Promise의 앞에 await
// Promise가 끝날 때까지 기다렸다가 다음 작업 수행
async function 함수명() {
  await 비동기_처리_메서드_명();
}
// 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한 대로 동작한다.

async & await 예외 처리

// 프로미스에서 에러 처리를 위해 .catch()를 사용했던 것처럼 async에서는 catch {}를 사용
async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); 
    }
  } catch (error) {
    console.log(error);
  }
}
// 코드를 실행하다가 발생한 네트워크 통신 오류뿐만 아니라
// 간단한 타입 오류 등의 일반적인 오류까지도 catch로 잡아낼 수 있다.
// 발견된 에러는 error 객체에 담기기 때문에 에러의 유형에 맞게 에러 코드를 처리해주면 된다.

0개의 댓글