JS Promise

Younchong·2021년 10월 19일
0

Callback

  • Promise 사용이유
    비동기처리를 위한 하나의 패턴이고, 전통적인 callback 함수는
    무분별한 callback 함수로 인한 callback 지옥으로 코드 가독성을 떨어뜨리고, 그로 인한 유지보수등의 문제 야기한다. + 에러처리 한계
    -> 이러한 단점을 보완하고, 비동기처리 시점을 명확하게 나타낼 수 있다.

Promise

  • 프로미스 생성
    Promise 생성자 함수로 new Promise 를 생성하면 자동으로 내부에 실행함수(executor)가 실행된다.
    실행함수는 resolve와 reject를 인자로 갖고, 비동기처리가 성공시와 실패시로 나눠서 호출된다.
let promise = new Promise(function(resolve, reject) {
// executor 실행
}
  • 프로미스 상태
                          fulfilled (resolve함수 호출)
    Pending ->                                                -> settled
                          rejected (reject함수 호출)
    로 구분.
    성공 혹은 실패만 존재(양립불가)
  • 프로미스 후속 처리 메소드

1 . then
기본 문법

promise.then(
function(result) { /* result를 다룸 */}
function(error) { /*error다룸 */}
);

then의 첫번째 인자는 promise 성공시 (resolve함수 호출됐을 때), 실행결과를 받고,
두번째 인자는 promise 실패시 (reject함수 호출시), 에러를 받고 사용된다.
그리고 then메소드는 promise를 반환한다.

  1. catch
    에러만 핸들링하고 싶을 경우.
    then과 동일하게 promise.catch(error) 뒤에 붙혀 사용하면 된다.
    Promise를 반환한다.
    catch(f1) === then(null, f1) 과 동일하다.
    하지만 catch를 사용하는게 가독성이 더 좋고, 비동기에서 발생하는 에러뿐만아니라 then내부에서 생기는 에러까지 처리할 수 있다.
    Ex) .then(f1, f2) 에서 만약 f1에서 에러가 발생하면 f2는 그 에러를 처리불가.

  2. finally
    결과에 상관없이 마무리가 필요할때 promise.filnally(f) 를 사용할 수 있다.
    finally(f) 와 then(f, f)가 유사하지만 다른점은
    finally는 인자가 없다.( 그래서 promise 결과를 알 수 없음)
    다음 핸들러에 결과와 에러를 자동으로 전달.

Promise chaining

여러개의 비동기처리를 할 때, 콜백으로만 처리하게 되면, 가독성이 떨어지고, 콜백헬이 발생하기 쉽다.
프로미스 후속 처리 메소드들을 체이닝해서 프로미스를 연결하여 사용할 수 있다.
(프로미스 후속 처리 메소드들의 반환값이 프로미스이기 때문에 promise chaining이 가능)

new Promise(function(resolve, reject) {

SetTimeout( () => resolve(1), 1000);

}.then(function(result) {

alert(result) // 1

return result * 2
}). then(function(result) {

alert(result) // 2

return result * 2
}) then(function(result) {

alert(result) // 4

return result * 2
})

위와 같이 사용된다.
Return에 프로미스를 반환해도 resolve의 결과값이 then으로 넘어간다.(비동기실행될경우)

Promise API

  1. Promise.all
    프로미스 배열을 받아서, 프로미스 실행 결과 값이 담긴 순서 그대로의 배열을 반환.
    let promise = Promise.all([. . .promises. . .])
    모든 promise가 실행 완료된 후 반환되고, 하나라도 거부되면, error와 함께 반환됨(promise.all의 결과값이 된다.)
  1. Promise.allSettled
    Promise.all 과는 달리 에러값이 나오더라도 배열내 각 프로미스의 상태와 값, 에러를 반환한다.
  1. Promise.race
    배열내의 가장 먼저 처리되는 promise 결과값 혹은 에러를 반환함.
  1. Promise.resolve/reject
    Promise.resolve(value) 는 결과값이 value인 이행상태의 promise 생성
    Promise.reject(error) 는 결과값이 error인 거부상태의 promise 생성
    (async, await 이후로는 잘 사용안함)

동작원리

Microtask Queue에 의해서 JS Engine내의 stack이 비었을 때(stack내부 작업들이 다 실행되고 난 후에) Microtask Queue내부에 있는 작업들이 실행됨. (프로미스의 .then/.catch/.finally 내 코드들).

async와 await

  • async
    async함수는 일반함수앞에 붙혀 사용하는데, 일반함수가 promise를 반환하게 합니다.
    async function f() {return 1;}. f().then(alert); // 1
  • await
    await는 async함수 안에서만 사용가능
    단어 그대로 프로미스가 처리될때까지 함수실행을 기다리게 한다.
    처리가 되면 그 결과와 함께 함수 실행.

0개의 댓글