병아리의 코딩 일기

Promise와 then(), catch(), finally() 본문

자바스크립트 ES6+/Promise

Promise와 then(), catch(), finally()

oilater 2023. 12. 29. 02:18

then()

  • 성공과 실패 핸들러 함수를 작성한다.
    • Promise 인스턴스를 반환한다. (값을 반환하는 것이 아님)
  • 파라미터
    • 첫번째 : 성공일 때 실행될 핸들러 함수
    • 두 번째 : 실패일 때 실행될 핸들러 함수
  • 실행자의 resolve(), reject()에
    • 파라미터 값을 다수 작성하더라도
    • 핸들러 함수는 처음 하나만 사용한다.
const obj = new Promise((resolve, reject) => {
  resolve(1, 2, 3);
});

obj.then(
  (value) => {
    console.log(value);
  },
  (reason) => {
    console.log(reason);
  }
);
  1. resolve(1, 2, 3);
  2. 파라미터에 값을 3개 작성했다.
  3. 실패(reject)가 발생하지 않으면
  4. reject()를 작성하지 않아도 딘다.
  5. obj.then((value) ⇒ {.1.}, (reason) ⇒ {.2.});resolve와 reject 모두 작성했지만 실행자에 resolve()만 있으므로
    const obj = new Promise((resolve) => {
      resolve(1, 2, 3);
    });
    
    obj.then((value) => {
      console.log(value + 2);
    });
    
  6. 첫 번째 함수만 작성해도 된다.
  7. then() 설명을 위해
  8. 실행자에서 resolve()가 실행되면 then()의 첫 번째 파라미터 함수가 실행된다.
  9. 이 때 resolve(1, 2, 3)에서 1, 2, 3을 파라미터로 넘겨주지만
  10. then((value) ⇒ {log(value)}의 value에 첫 번째 값인 1만 설정된다.
  11. 그래서 실행결과로 1이 출력되었다.
  12. 다수의 파라미터 값을 넘겨주려면 배열, Object 등을 사용해야 한다.

then()의 return

  • then()에서 Promise의 인스턴스를 반환한다.
    • return 값을 반환하지 않는다.
    • method chain에서 this를 return하는 것과 같은 개념이다.
    • 따라서 then().then() 형태처럼
    • then()을 연속해서 호출할 수 있다.
  • return 값을 [[PromiseValue]]에 설정하고
    • [[PromiseValue]] 값을 다음 then()의 파라미터 값으로 넘겨준다.
    const obj = new Promise((resolve) => {
      resolve(100);
    });
    
    obj
      .then((value) => {
        return value + 50;
      })
      .then((res) => {
        console.log(res);
      });
    
    1. obj.then((value) ⇒ {…}
    2. value 파라미터에 100이 설정된다.
    3. return value + 50;
    4. 150을 반환하지 않고 인스턴스를 반환한다.
    5. return을 작성하지 않으면
    6. undefined를 [[PromiseValue]]에 설정한다.
    7. then((param) ⇒ {log(param)});실행 결과에 150이 출력된다.
    8. param에 [[PromiseValue]] 값인 150이 설정된다.

catch()

  • 실패(reject)의 핸들러 함수를 작성한다.
    • then()의 두 번쨰 파라미터를 작성하지 않고
    • 대신에 catch(param)를 작성한다.
    const check = false;
    const obj = new Promise((resolve, reject) => {
      check ? resolve(check) : reject(1, 2, 3);
    });
    
    obj
      .then((value) => {
        console.log(value);
      })
      .catch((value) => {
        console.log(value);
      });
    
    1. check ? resolve(check) : reject(1, 2, 3);
    2. check 값이 false이므로 reject()를 호출하게 되며 파라미터 값으로 1, 2, 3을 넘겨준다.
    3. catch((value) ⇒ {log(value)})
    4. then()의 두 번째 파라미터에 함수를 작성하지 않고 별도로 catch()를 작성했다.
    5. reject()가 호출되면 catch(value)가 실행된다.
    6. 1, 2, 3을 파라미터 값으로 넘겨주지만 value에 첫 번째 값인 1만 설정되다.
    • return 문의 표현식 평가 결과를 [[PromiseValue]]에 설정한다.
  • Promise 인스턴스를 반환하므로
    • catch().then()처럼
    • 이어서 then()을 호출할 수 있다.
    • [[PromiseValue]] 값을 then()의 파라미터 값으로 넘겨준다.
    const obj = new Promise((resolve, reject) => {
      resolve(100);
    });
    
    obj
      .then((value) => {
        throw "에러";
      })
      .catch((catch1) => {
        console.log("catch1:" + catch1);
        return "정상";
      })
      .then((param) => {
        console.log("then:" + param);
      })
      .catch((catch2) => {
        console.log("catch2:" + catch2);
      });
    
    [실행 결과]
    catch1:에러
    then:정상
    

finally()

  • 성공, 실패에 관계 없이
    • 파라미터의 핸들러 함수가 실행된다.
    • 핸들러 함수에 파라미터가 없다.
    • ES2018부터 지원한다.
  • 활용 측면이지만 then(), catch()의
    • 같은 코드를 finally()에 작성하면
    • 코드 중복을 피할 수 있다.
const obj = new Promise((resolve, reject) => {
  resolve(100);
});

obj
  .then((value) => {
    console.log(value);
    return 200;
  })
  .catch((reason) => {
    console.log(reason);
  })
  .finally((param) => {
    console.log("finally : " + param);
  });
  1. resolve(100);
  2. then()의 핸들러 함수가 호출된다.
  3. obj.then((value) => {return 200;}catch()를 실행하지 않고 finally()를 실행한다.
  4. 200을 [[PromiseValue]]에 설정한다.
  5. finally((param)⇒ {…}설명을 위해 작성한 것이다.[[PromiseVAlue]]값이 param에 설정되지 않는다.
  6. then()에서 200을 return 하지만
  7. 문법적으로 param 파라미터를 사용하지 않으며
  8. 파라미터를 작성하지 않더라도 에러가 나지 않지만[실행 결과]에 undefined가 출력된다.
  9. undefined가 설정되므로 의미가 없다.
728x90
반응형
LIST