카테고리 없음

promise의 요청상태

인재재 2024. 7. 1. 01:44

Promise의 요청상태

  • 대기상태 (pending)
  • 이행상태 (fulfilled)
  • 거부상태 (rejected)

대기 상태

  • 비동기 처리가 수행되기 이전의 상태를 의미하며 이행하지도 거부하지도 않은 상태를 의미한다.
const newPromise = () => { return new Promise(); };​

이행 상태

  • Promise를 통하여서 비동기 호출을 하였을 때, '성공’적으로 호출이 된 경우
new Promise (function (resolve, reject)){ resolve(); }​

거부 상태

  • Promise를 통하여 비동기 호출을 하였으나 호출이 ‘실패’ 된 경우
new Promise(function(resolve, reject) { reject(); });​

than의 두번째 인수로 오류처리 = catch

fetch('https://api.example.com/data') 
.then((response) => response.json())
// response객체반환시 response.json() 호출, 두번째 인수가 없어서 다음
// than에서 오류를 잡아냄 .then(undefined, (error) => { console.log('error'); })
// 첫번째 than에서 오류가 없을시 두번째 than은 실행되지 않음
// undefined = 아무 작업도 하지 않겠다는 의미, 바로 두번째 인수로 넘어감 
// 세번째 than이 있을 경우에 undefined가 넘어가게됨
fetch('https://api.example.com/data') 
.then((response) => response.json()) 
.then((data) => { console.log('data:', data); }) 
.catch((error) => { console.log('error'); }); 
/// catch 사용 시 Promise 체인에서 발생할 수 있는 모든 오류를 catch 블록에서 한 번에 처리

 

 
  1. 질문:

    catch와 .then의 차이점

    답변:

    , JavaScript에서 catch .then의 두 번째 인자로 받는 함수는 비슷한 기능을 하지만, 사용 방법과 시맨틱스에 몇 가지 차이점이 있습니다.
    1. catch 사용:catch는 프로미스 체인에서 발생하는 모든 에러를 잡는 데 사용됩니다. 프로미스 체인에서 어느 지점에서 에러가 발생하든 간에, 해당 에러는 체인의 끝에 있는 catch 블록으로 전달됩니다.
    promise .then(result => { // 성공 시 실행 }) .catch(error => { // 에러 발생 시 실행 });
    1. .then의 두 번째 인자로 받는 함수 사용:.then 메서드의 두 번째 인자로 에러 핸들러를 전달할 수 있습니다. 이 방법은 해당 .then 블록에서 발생하는 에러만을 처리합니다. 이 경우 프로미스 체인 내에서 특정 부분의 에러만 잡아낼 수 있습니다.
    promise .then( result => { // 성공 시 실행 }, error => { // 에러 발생 시 실행 } );

    차이점 요약:

    • 범위:
      • catch는 체인 전체에서 발생하는 모든 에러를 잡습니다.
      • .then의 두 번째 인자는 해당 .then 블록 내에서 발생하는 에러만 잡습니다.
    • 위치:
      • catch는 보통 체인의 마지막에 위치합니다.
      • .then의 두 번째 인자는 체인의 중간에 위치할 수 있습니다.
    • 가독성:
      • catch를 사용하는 방법이 더 가독성이 좋고 명확합니다. 체인의 어디에서 에러가 발생하든 catch 블록에서 모두 처리할 수 있기 때문입니다.

    예시:

    // 예제 1: catch 사용 promise .then(result => { // 일부 코드 return anotherPromise; }) .then(result => { // 일부 코드 }) .catch(error => { // 이곳에서 체인 전체의 에러 처리 }); // 예제 2: .then의 두 번째 인자 사용 promise .then( result => { // 일부 코드 return anotherPromise; }, error => { // 첫 번째 then에서 발생하는 에러만 처리 } ) .then( result => { // 일부 코드 }, error => { // 두 번째 then에서 발생하는 에러만 처리 } );
    위의 예시에서 보듯이, catch를 사용하면 에러 처리가 단순하고 체인의 마지막에서 한 번에 처리할 수 있습니다. 반면 .then의 두 번째 인자를 사용하면 각 블록마다 별도로 에러 처리를 할 수 있습니다. (수정됨)
     
     
     
    ---------------------------------------------------------------

    질문:

    결국 then의 두번째 인자로 받는것도 체이닝되어서 뒤로 전달되니까 catch랑 똑같은거아닌가?

    답변:

    좋은 질문입니다! then의 두 번째 인자와 catch의 동작을 비교할 때, 미묘하지만 중요한 차이점이 있습니다.
    1. .then의 두 번째 인자:
    .then의 두 번째 인자로 전달되는 함수는 해당 then 블록 내에서 발생한 에러만 처리합니다. 이 블록 내에서 에러가 발생하면 그 즉시 처리하고, 그 후의 체이닝된 then 블록들로 에러가 전달되지 않습니다.
    promise .then( result => { // 성공 시 실행 return anotherPromise; }, error => { // 첫 번째 then에서 발생한 에러만 처리 console.log('첫 번째 then에서 에러 발생:', error); } ) .then( result => { // 두 번째 then 블록 }, error => { // 두 번째 then 블록에서 발생한 에러 처리 console.log('두 번째 then에서 에러 발생:', error); } ) .catch(error => { // catch 블록 console.log('catch에서 에러 처리:', error); });
    위 예제에서, 첫 번째 then 블록 내에서 에러가 발생하면 두 번째 인자로 전달된 에러 핸들러가 이를 처리합니다. 이 에러는 체인의 다음 then 블록으로 전달되지 않으므로 catch 블록으로 가지 않습니다.
    1. catch 사용:
    catch는 프로미스 체인에서 발생하는 모든 에러를 잡습니다. 프로미스 체인의 어느 블록에서 에러가 발생하든 catch 블록이 이를 처리합니다.
    promise .then(result => { // 일부 코드 return anotherPromise; }) .then(result => { // 일부 코드 }) .catch(error => { // 이곳에서 체인 전체의 에러 처리 console.log('catch에서 에러 처리:', error); });

    차이점 요약:

    에러 전달: .then의 두 번째 인자는 해당 블록 내의 에러를 처리하고 체인의 다음 블록으로 에러를 전달하지 않습니다. 반면 catch는 체인의 어느 블록에서 발생한 에러든 모두 잡아서 처리합니다.

    에러 처리 위치: .then의 두 번째 인자는 체인의 중간에서 특정 블록의 에러를 처리하는 데 사용됩니다. catch는 체인의 끝에서 모든 에러를 처리하는 데 사용됩니다.

    •  

    결론:

    then의 두 번째 인자는 특정 블록의 에러를 처리할 때 유용하며, 이 에러가 체인의 다른 부분으로 전파되지 않도록 합니다. 반면 catch는 체인의 어느 부분에서든 발생하는 모든 에러를 잡아내어 처리합니다. 두 방법은 서로 보완적인 역할을 하며, 상황에 맞게 적절히 사용할 수 있습니다. (수정됨)
     

    ----------------------------------------------

    질문:

    두번째 인자를 가진 .then을 마지막에 쓰면 catch랑 똑같은거아니야?

    답변:

    , .then의 두 번째 인자를 프로미스 체인의 마지막에 사용하면 catch와 매우 유사하게 동작합니다. 하지만 여전히 몇 가지 미묘한 차이가 있습니다.

    .then의 두 번째 인자를 마지막에 사용할 때:

    promise .then(result => { // 성공 시 실행 return anotherPromise; }) .then(result => { // 성공 시 실행 }, error => { // 체인의 마지막에서 에러 처리 console.log('then의 두 번째 인자로 에러 처리:', error); });
    이 경우, 에러가 발생하면 마지막 then 블록의 두 번째 인자가 그 에러를 처리합니다. 이로 인해 catch와 거의 동일하게 동작하게 됩니다. 하지만 여기에도 약간의 차이점이 있습니다.

    catch를 사용할 때:

    promise .then(result => { // 성공 시 실행 return anotherPromise; }) .then(result => { // 성공 시 실행 }) .catch(error => { // 체인의 마지막에서 에러 처리 console.log('catch 블록에서 에러 처리:', error); });

    차이점 요약:

    1. 코드 가독성:
      • catch는 에러 처리를 위한 명시적인 블록을 제공하므로, 에러 처리 코드가 더 명확하게 드러납니다.
      • .then의 두 번째 인자를 사용하면, 성공과 에러 처리가 같은 then 블록 내에서 처리되므로, 코드가 다소 혼란스러울 수 있습니다.
    1. 체인의 중간 에러 처리:
      • catch를 사용하면 체인의 어느 블록에서든 발생한 에러를 모두 한 곳에서 처리할 수 있습니다.
      • .then의 두 번째 인자를 사용하면 특정 then 블록의 에러만 처리할 수 있으며, 체인의 다른 부분에서 발생한 에러는 처리하지 않습니다.

    예시 비교:

    // 예시 1: catch 사용 promise .then(result => { // 일부 코드 return anotherPromise; }) .then(result => { // 일부 코드 }) .catch(error => { // catch 블록에서 체인 전체의 에러 처리 console.log('catch 블록에서 에러 처리:', error); }); // 예시 2: then의 두 번째 인자 사용 promise .then(result => { // 일부 코드 return anotherPromise; }) .then(result => { // 일부 코드 }, error => { // then의 두 번째 인자로 체인 전체의 에러 처리 console.log('then의 두 번째 인자로 에러 처리:', error); });
    두 예시 모두 마지막에서 에러를 처리하는 방법을 보여줍니다. 실제 동작 면에서는 매우 유사하지만, catch를 사용하는 것이 더 명확하고 직관적입니다. 따라서, .then의 두 번째 인자를 마지막에 사용하는 것은 가능하지만, 에러 처리의 명확성과 가독성을 위해 catch를 사용하는 것이 더 좋습니다. catch는 에러 처리를 위한 표준적인 방법이므로, 코드의 가독성과 유지보수성 면에서 이점을 가집니다. (수정됨)
     
    ---------------------------------------------------------

    질문:

    catch가 마지막까지 에러가 전달될 수 있는 이유가 뭐야? 그리고 .then에 인자가 하나만 있으면 에러가 발생했을 때 어떻게처리되지?

    답변:

    좋은 질문입니다! 이를 이해하기 위해서는 프로미스 체인의 동작 방식을 자세히 살펴볼 필요가 있습니다.
    1. catch가 마지막까지 에러가 전달될 수 있는 이유
    catch가 마지막까지 에러를 전달받을 수 있는 이유는 프로미스의 체이닝 특성 때문입니다. 프로미스 체인은 각 then 블록이 새로운 프로미스를 반환하기 때문에, 이전 단계에서 발생한 에러가 다음 단계로 전달될 수 있습니다. 에러가 발생하면 프로미스는 거부(rejected) 상태가 되며, 그 상태는 체인의 다음 프로미스들로 전달됩니다.
    promise .then(result => { // 첫 번째 then 블록 return anotherPromise; }) .then(result => { // 두 번째 then 블록 }) .catch(error => { // 이곳에서 체인 전체의 에러 처리 console.log('catch 블록에서 에러 처리:', error); });
    위 예제에서 첫 번째 또는 두 번째 then 블록에서 에러가 발생하면, 프로미스는 거부 상태가 되고, 이 거부 상태는 체인의 마지막 catch 블록으로 전달됩니다.
    1. .then에 인자가 하나만 있으면 에러가 발생했을 때 어떻게 처리되는지
    then 메서드에 성공 콜백 함수(첫 번째 인자)만 전달하고 에러 콜백 함수(두 번째 인자)를 생략하면, 에러는 해당 then 블록을 건너뛰고 다음 catch 블록 또는 다음 then 블록의 에러 핸들러로 전달됩니다. 이 때문에 에러 처리가 더 간편해집니다.
    promise .then(result => { // 첫 번째 then 블록 return anotherPromise; }) .then(result => { // 두 번째 then 블록 }) .catch(error => { // 이곳에서 체인 전체의 에러 처리 console.log('catch 블록에서 에러 처리:', error); });
    이 예제에서, then 블록 중 어느 한 곳에서 에러가 발생하더라도, catch 블록이 그 에러를 처리합니다. 이는 에러가 발생한 경우, 프로미스 체인이 계속해서 거부 상태로 전달되기 때문입니다.

    정리:

    1. catch가 마지막까지 에러를 전달받는 이유:
      • 프로미스 체인은 각 then이 새로운 프로미스를 반환하기 때문에, 거부 상태가 발생하면 그 상태가 체인의 다음 프로미스로 전달됩니다.
      • catch는 프로미스 체인의 끝에서 모든 거부 상태를 잡아내어 처리합니다.
    1. .then에 인자가 하나만 있을 때:
      • 에러 콜백 함수(두 번째 인자)를 생략하면, 에러는 다음 then 또는 catch 블록으로 전달됩니다.
      • 이는 프로미스 체인의 중간에서 에러가 발생하더라도, 체인의 끝에서 일괄적으로 에러를 처리할 수 있게 합니다.
    이러한 특성 덕분에 프로미스를 사용할 때, 에러 처리가 더욱 일관되고 간편해집니다. catch 블록은 프로미스 체인의 마지막에 위치하여 모든 에러를 처리할 수 있도록 설계되어 있습니다. (수정됨)