스프린터스 #3 Promise - async, await

HR.lee·2022년 4월 18일
0

스프린터스

목록 보기
3/25

취업할때까지 달리기!

  • 4월 18일(월)
    1. var, let, const 차이를 설명
    2. 이벤트 버블링과 캡처링에 대해 설명
    3. Promise를 사용한 비동기 통신과 async, await 를 사용한 비동기 통신의 차이를 설명
    4. 호이스팅에 대해서 설명
    5. virtual DOM에 대해 설명
    6. 클래스형과 함수형 컴포넌트의 차이점

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#%EC%B2%B4%EC%9D%B4%EB%8B%9D
https://elvanov.com/2597
https://velog.io/@rohkorea86/Promiseis-%EB%B9%84%EB%8F%99%EA%B8%B0%EB%8F%99%EA%B8%B0%EC%97%90%EC%84%9C-Promise%EA%B9%8C%EC%A7%80

먼저 동기와 비동기의 차이

동기 특징
동시에 여러 작업을 수행할 수 없다.
흐름을 예측하기 쉽다. 먼저 수행되고 나중에 수행되는 것들이 명확하다.
비동기 특징
동시에 여러 작업을 수행할 수 있다.
흐름을 예측하기 어렵다. (무엇이 먼저 완료될 지 보장할 수 없다.)

즉, promise, async, await 얘들은 비동기 작업을 마치 동기적으로, 즉 비동기 작업이 끝난 후 특정 작업들을 실행할 수 있도록 순서를 정해주기 위해 존재합니다.

프로미스의 도입배경

콜백지옥을 끝내기 위해...

콜백함수("call" + "back")

콜백지옥을 불러오는 콜백함수는 자바스크립트의 비동기성을 표현하고 관리하는 가장 일반적인 기법이자 가장 기본적인 비동기 패턴입니다. 콜백이 있었고 그리고 프로미스가 생겼고 그리고...

콜백함수가 실행됐다는 것으로 요청한 작업이 끝났음을 알리고, 작업의 결과물을 콜백함수를 통해 사용가능하게 됩니다.

콜백지옥

콜백함수가 늘어나면 늘어날 수록 코드의 깊이가 늘어나 더이상 헤어날 수 없다는 유머 입니다.
코드 관점에서 콜백함수는 중첩으로 들여쓰기(nesting)가 반복되어 가독성이 떨어지게 됩니다.이런 코드의 특성과 효과가 꼭 지옥같다고 해서 콜백지옥이라고 합니다.

async await의 도입배경

than지옥을 끝내기 위해...

promise는 문법이 아닌 객체.

Promise의 구조

Promise 는
비동기 작업을 생성/시작하는 선언부(new Promise(...))와
작업 이후의 동작부(then, catch)를 분리함으로써 기존의 러프한 비동기 작업보다 유연한 설계가 가능합니다.

프로미스를 만드는 방법은 다음과 같습니다.
구현하려는 비동기 함수안에 Promise 객체를 만드는 로직을 넣습니다.

  1. 선언부에서 생성자 함수를 new를 통해 인스턴스화 a = new Promise
  2. 이때 생성자 함수에 executor를 화살표함수 형태로 넣기
  3. 동작부는 executor가 준 resolve와 reject를 인자로 전달 받습니다.

executor란?

프로미스에서만 쓰이는 특별한 함수입니다.
1. executor는 첫번째 인수로 resolve, 두번째 인수로 reject 를 받습니다.
2. resolve 는 executor 내에서 호출할 수 있는 함수입니다. “비동기 작업이 성공했어!” 라는 뜻입니다.
3. reject 또한 executor 내에서 호출할 수 있는 함수입니다. “이 비동기 작업이 실패했어…” 라는 뜻입니다.

이외 executor 를 만들때 고려해야 할 점

  1. executor 내부에서 에러가 throw 된다면 해당 에러로 reject 가 수행됩니다.
  2. executor 의 리턴 값은 무시됩니다.
  3. 첫 번째 reject 혹은 resolve 만 유효합니다. (두 번째부터는 무시됩니다. 이미 해당 함수가 호출되었다면 throw 또한 무시됩니다.)

비동기 처리함수가 어떤 결과값(리졸브나 리젝트)을 갖는냐에 따라,

생성된 프로미스 객체는 아래와 같은 3가지 상태값을 갖습니다.
1. pending(비동기 처리 로직이 아직 완료되지 않은 상태)
new Promise로 Promise가 생성된 직후부터 resolve나 reject가 호출되기 전까지의 순간을 pending 이라고 합니다.

  1. fullfilled(처리가 완료되어 프로미스가 결과값을 반환한 상태)
    만약 비동기 처리함수 값이 성공이라면 resolve 메소드가 호출되고,resolve 메소드의 인자로 설정한, 비동기 함수의 결과값이 전달됩니다. 이 결과값은 then을 통해 후속 처리됩니다.

  2. Rejected(처리가 실패하거나 오류가 발생한 상태)
    catch 메서드로 오류를 전달할 수 있음

비동기 성공 -> resolve 메소드 실행 -> 이때 resolve 메소드 인자에 이미 설정한 처리함수의 결과값이 (resolve 메소드를 통해) 이동 -> then메서드를 통해 성공의 후속처리 실행

프로미스 객체를 쓰는 이유

일반적으로 웹 애플리케이션을 구현할 때 서버에서 데이터를 요청하고 받아오기 위해 API를 사용하는데, API가 실행되면 서버에다가 데이터 보내달라는 요청을 보내고,
여기서 데이터를 받아오기도 전에 마치 데이터를 다 받아온 것 마냥 화면에 데이터를 표시하려고 하면 오류가 발생하거나 빈 화면이 뜹니다. 이같은 문제를 해결하기 위해 promise를 사용합니다

then() 과 catch() 문에는 체인을 걸수 있는데, 이러한 체이닝을 통해 비동기 로직의 성공 여부에 따른 분기 처리가 가능합니다.

async와 await

async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법입니다. 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와주죠.

async await 문법 덕택에 비동기에 대한 사고를 덜해도 되게 되었습니다.
왜냐면 promise 객체를 하나의 흐름처럼 처리하거든요.

async await 문법의 조건

  1. await 는 async로 선언한 함수 안에서만 동작한다.
  2. async 함수의 리턴 값은 무조건 Promise 객체이다.
  3. await 은 then 과 catch 의 동작을 모두 알아서 흐름대로 처리하지만 에러 핸들링 기능은 없기 때문에 try-catch() 문을 활용해야 한다.

async await 문법의 장점

콜백 함수나 .then()을 안써도 된다. .then()지옥과 콜백지옥을 피할 수 있다는 얘기
코드가 길어지면 길어질수록, async/await 를 활용한 코드가 가독성이 좋다.
비동기 코드가 동기 코드처럼 읽히게 해준다. 코드 흐름을 이해 하기 쉽다.

두개의 차이점

promise는 비동기작업이 끝났는지, 성공했는지, 실패했는지를 알려주려 한다면
await은 키워드를 붙이면, 비동기 작업이 결과를 낼 때까지 기다려주는 역할을 합니다.
비동기 중 가장 필요한 옵션은 '결과가 나올때까지 오류를 내지 않고 기다리는 것'이기 때문에 사용자의 편의를 위해 쓰지 않는 옵션들을 자동화하고 안전한 방식으로 코딩할 수 있게 나온 것.

await이 무조건 옳지 않음, 프로미스 문법을 써야 할 때

then은 비동기가 연속적으로 일어나는 상황에서 각 Promise 객체마다 다른 로직으로, 체이닝을 구성하려고 할때, 즉 커스텀을 하고 싶을 때 더 유용하게 사용할 수 있습니다.

또한 여러 Promise 객체를 병렬적으로 처리하고 싶을 때, 예를 들어 각각의 Promise 객체들이 모두 결과를 반환한 뒤에 이후 로직을 처리하고 싶을 때는 Promise.all 을 활용할 수 있습니다.

profile
It's an adventure time!

0개의 댓글