[javascript] Promise catch에서 오류를 다시 던짐

튜토리얼에서 다음 코드를 찾았습니다.

promise.then(function(result){
    //some code
}).catch(function(error) {
    throw(error);
});

나는 약간 혼란 스럽습니다. catch 호출이 어떤 일을 수행합니까? 그것은 단순히 잡힌 것과 같은 오류를 던지기 때문에 아무런 영향을 미치지 않는 것 같습니다. 나는 이것을 정규적인 try / catch가 어떻게 작동하는지에 기초한다.



답변

당신이 보여줄 때 알몸으로 잡고 던지는 것은 의미가 없습니다. 코드 추가 및 느린 실행 외에는 유용한 작업을 수행하지 않습니다. 따라서 다시 .catch()던지려는 경우에서 원하는 작업 .catch()이 있어야 합니다 . 그렇지 않으면 .catch()전체를 제거해야합니다 .

일반적인 구조의 일반적인 요점 .catch()은 오류를 기록하거나 파일 닫기와 같은 일부 상태를 정리 하는 것과 같은 작업 을 실행 하려고하지만 약속 체인이 거부 된 상태로 계속되기를 원할 때입니다.

promise.then(function(result){
    //some code
}).catch(function(error) {
    // log and rethrow 
    console.log(error);
    throw error;
});

튜토리얼에서는 사람들에게 오류를 포착 할 수있는 위치를 보여 주거나 오류를 처리하는 개념을 가르치고 다시 던지기 위해있을 수 있습니다.


잡기 및 다시 던지기에 대한 몇 가지 유용한 이유는 다음과 같습니다.

  1. 오류기록하고 싶지만 약속 체인을 거부 된 상태로 유지합니다.
  2. 오류를 다른 오류로 바꾸고 싶습니다. (체인의 끝에서 종종 쉽게 오류 처리를 위해). 이 경우 다른 오류가 다시 발생합니다.
  3. 약속 체인이 계속되기 전에 (예 : 닫기 / 사용 가능한 리소스) 많은 처리수행하고 싶지만 약속 체인이 거부 된 상태로 유지되기를 원합니다.
  4. 실패가있는 경우 약속 체인의이 지점에서 디버거대한 중단 점을 배치 할 지점을 원합니다 .

그러나 catch 핸들러에 다른 코드가없는 동일한 오류를 일반 catch 및 rethrow는 정상적인 코드 실행에 유용한 작업을 수행하지 않습니다.


답변

.then().catch()메서드는 모두 Promises를 반환하며, 두 핸들러 중 하나에서 Exception을 throw하면 반환 된 promise는 거부되고 Exception은 다음 거부 핸들러에서 포착됩니다.

다음 코드에서는 첫 번째 예외가 발생하고 두 번째 예외가 발생 .catch()합니다 .catch().

new Promise((resolve, reject) => {
    console.log('Initial');

    resolve();
})
.then(() => {
    throw new Error('Something failed');

    console.log('Do this'); // Never reached
})
.catch(() => {
    console.log('Something failed');
    throw new Error('Something failed again');
})
.catch((error) => {
    console.log('Final error : ', error.message);
});

두 번째 .catch()는 이행 된 Promised를 반환하고 .then()핸들러를 호출 할 수 있습니다.

new Promise((resolve, reject) => {
    console.log('Initial');

    resolve();
})
.then(() => {
    throw new Error('Something failed');

    console.log('Do this'); // Never reached
})
.catch(() => {
    console.log('Something failed');
    throw new Error('Something failed again');
})
.catch((error) => {
    console.log('Final error : ', error.message);
})
.then(() => {
    console.log('Show this message whatever happened before');
});

유용한 참조 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch

도움이 되었기를 바랍니다!


답변

생략하면 큰 차이가 없습니다. catch메서드 호출을 완전히 .

추가되는 유일한 것은 추가 마이크로 태스크이며, 실제로는 catch조항 없이 실패한 약속의 경우보다 나중에 약속의 거부를 알 수 있음을 의미합니다 .

다음 스 니펫은이를 보여줍니다.

var p;
// Case 1: with catch
p = Promise.reject('my error 1')
       .catch(function(error) {
          throw(error);
       });

p.catch( error => console.log(error) );
// Case 2: without catch
p = Promise.reject('my error 2');

p.catch( error => console.log(error) );

두 번째 거부가 첫 번째 거부 전에 어떻게보고되는지 확인하십시오. 이것이 유일한 차이점입니다.


답변

따라서 귀하의 질문은 “프로 미스 체인에서 .catch()메소드가 수행하는 작업은 무엇입니까?”입니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw

throw 문은 “중지되고 (throw 후 문이 실행되지 않음) 제어가 호출 스택의 첫 번째 catch 블록으로 전달됩니다. 호출자 함수 중에 catch 블록이 없으면 프로그램이 종료됩니다.”

Promise 체인에서 .then()메소드는 어떤 유형의 데이터 청크를 반환합니다. 이 청크 반환은 약속을 완료합니다. 데이터가 성공적으로 반환되면 약속이 완료됩니다. .catch()같은 방식으로 방법을 생각할 수 있습니다 . .catch()그러나 실패한 데이터 검색을 처리합니다. throw 문은 약속을 완료합니다. 때때로, 당신은 .catch((err) => {console.log(err))} 약속 체인을 완성 할 개발자들이 사용 하는 것을 보게 될 것입니다.


답변

실제로 다시 던질 필요가 없습니다. Promise.catch를 비워 두십시오. 그렇지 않으면 거부 처리를 취소 한 다음 코드를 try catch로 래핑 한 다음 전달되는 오류를 자동으로 포착합니다.

try{
  promise.then(function(result){
    //some code
  }).catch(function(error) {
    //no need for re throwing or any coding. but leave this as this otherwise it will consider as un handled
  });
}catch(e){
  console.log(e);
  //error can handle in here
}


답변

promise 체인에서는 .catch를 사용하는 것이 좋습니다.

ex 함수 f2에서 : .then (…). catch (e => reject (e));

  • test1-try catch 사용
  • test2-try 또는 .catch없이
  • test3-.catch 사용
function f1() {
    return new Promise((resolve, reject) => {
        throw new Error('test');
    });
}

function f2() {
    return new Promise((resolve, reject) => {
        f1().then(value => {
            console.log('f1 ok ???');
        }).catch(e => reject(e));
    });
}

function test1() {
    console.log('test1 - with try catch - look in F12');
    try {
      f2().then(() => { // Uncaught (in promise) Error: test
        console.log('???'); });
    } catch (e) {
      console.log('this error dont catched');
    }
}

function test2() {
    console.log('test2 - without try or .catch - look in F12');
    f2(); // Uncaught (in promise) Error: test
}

function test3() {
  console.log('test3 - with .catch');
  f2().then(value => {
    console.log('??');
  }).catch(e => {
    console.log(' now its ok, error ', e);
  })
}

setTimeout(() => { test1();
  setTimeout(() => { test2();
    setTimeout(() => { test3();
    }, 100);
  }, 100);
}, 100);


답변