then, catch, finally_JavaScript

miin·2022년 1월 3일
0

Java Script

목록 보기
18/35
post-thumbnail

then (value)

promise.then(
  function(result) { /* 결과(result)를 다룹니다 */ },
  function(error) { /* 에러(error)를 다룹니다 */ }
);
  • .then의 첫 번째 인수는 프라미스가 이행되었을 때 실행되는 함수이고, 여기서 실행 결과를 받는다
  • .then의 두 번째 인수는 프라미스가 거부되었을 때 실행되는 함수이고, 여기서 에러를 받는다
let promise = new Promise(function(resolve, reject) {
  setTimeout(() => resolve("done!"), 1000);
});

// resolve 함수는 .then의 첫 번째 함수(인수)를 실행한다.
promise.then(
  result => alert(result), // 1초 후 "done!"을 출력
  error => alert(error) // 실행되지 않음
);

첫 번째 함수가 실행되었다
프라미스가 거부된 경우에는 아래와 같이 두 번째 함수가 실행됩니다.

let promise = new Promise(function(resolve, reject) {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

// reject 함수는 .then의 두 번째 함수를 실행한다.
promise.then(
  result => alert(result), // 실행되지 않음
  error => alert(error) // 1초 후 "Error: 에러 발생!"를 출력
);

작업이 성공적으로 처리된 경우만 다루고 싶다면 .then에 인수를 하나만 전달하면 된다.

let promise = new Promise(resolve => {
  setTimeout(() => resolve("done!"), 1000);
});

promise.then(alert); // 1초 뒤 "done!" 출력

catch (error)

  • 에러가 발생한 경우만 다루고 싶다면 .then(null, errorHandlingFunction)같이 null을 첫 번째 인수로 전달하면 된다.
  • .catch(errorHandlingFunction)를 써도 되는데, .catch는 .then에 null을 전달하는것과 동일하게 작동한다
let promise = new Promise((resolve, reject) => {
  setTimeout(() => reject(new Error("에러 발생!")), 1000);
});

// .catch(f)는 promise.then(null, f)과 동일하게 작동합니다
promise.catch(alert); // 1초 뒤 "Error: 에러 발생!" 출력

.catch(f)는 문법인 간결하다는 점만 빼고 .then(null, f)와 완벽하게 같다

finally

  • 프라미스가 처리되면(이행이나 거부) f가 항상 실행된다는 점에서 .finally(f) 호출은 .then(f, f)과 유사하다
  • 쓸모가 없어진 로딩 인디케이터(loading indicator)를 멈추는 경우같이, 결과가 어떻든 마무리가 필요하면 finally가 유용하다
new Promise((resolve, reject) => {
  /* 시간이 걸리는 어떤 일을 수행하고, 그 후 resolve, reject를 호출함 */
})
  // 성공·실패 여부와 상관없이 프라미스가 처리되면 실행됨
  .finally(() => 로딩 인디케이터 중지)
  .then(result => result와 err 보여줌 => error 보여줌)
  • finally는 .then(f, f)과 완전히 같진 않다
  • finally 핸들러엔 인수가 없다.
  • finally에선 프라미스가 이행되었는지, 거부되었는지 알 수 없다.
  • finally에선 절차를 마무리하는 ‘보편적’ 동작을 수행하기 때문에 성공·실패 여부를 몰라도 된다.
  • finally 핸들러는 자동으로 다음 핸들러에 결과와 에러를 전달합니다.

result가 finally를 거쳐 then까지 전달

new Promise((resolve, reject) => {
  setTimeout(() => resolve("결과"), 2000)
})
  .finally(() => alert("프라미스가 준비되었습니다."))
  .then(result => alert(result)); // <-- .then에서 result를 다룰 수 있음

프라미스에서 에러가 발생하고 이 에러가 finally를 거쳐 catch까지 전달

new Promise((resolve, reject) => {
  throw new Error("에러 발생!");
})
  .finally(() => alert("프라미스가 준비되었습니다."))
  .catch(err => alert(err)); // <-- .catch에서 에러 객체를 다룰 수 있음

finally는 프라미스 결과를 처리하기 위해 만들어 진 게 아니다.
프라미스 결과는 finally를 통과해서 전달된다.

두번 resolve 하기?

let promise = new Promise(function(resolve, reject) {
  resolve(1);

setTimeout(() => resolve(2), 1000);
});

promise.then(alert);

출력결과 -> 1
첫 번째 reject/resolve 호출만 고려대상이기 때문에 두 번째 resolve는 무시되기 때문

>프라미스로 지연 만들기
내장 함수 setTimeout은 콜백을 사용한다. 프라미스를 기반으로 하는 동일 기능 함수를 만들어보자
함수 delay(ms)는 프라미스를 반환해야 한다. 반환되는 프라미스는 아래와 같이 .then을 붙일 수 있도록 ms 이후에 이행되어야 한다.
```js
function delay(ms) {
  // 여기에 코드 작성
}

delay(3000).then(() => alert('3초후 실행'));

해답

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

delay(3000).then(() => alert('3초후 실행'));

답안에서 resolve가 인수 없이 호출되었다.
함수 delay는 지연 확인 용이기 때문에 반환 값이 필요 없다.

0개의 댓글