[javascript] 그 전후에 어획물 배치

.catch중첩 약속에 BEFORE와 AFTER를 넣는 것의 차이점을 이해하는 데 어려움이 있습니다.

대안 1 :

test1Async(10).then((res) => {
  return test2Async(22)
    .then((res) => {
      return test3Async(100);
    }).catch((err) => {
      throw "ERROR AFTER THEN";
    });
}).then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});

대안 2 :

test1Async(10).then((res) => {
   return test2Async(22)
     .catch((err) => {
        throw "ERROR BEFORE THEN";
      })
      .then((res) => {
        return test3Async(100);
      });
  }).then((res) => {
    console.log(res);
  }).catch((err) => {
    console.log(err);
  });

각 함수의 동작은 다음과 같습니다. number가 <0test2 이면 test1은 실패하고 number가 아니면 > 10test3은 실패합니다 100. 이 경우 test2는 실패 만합니다.

나는 실행하고 test2Async를 실패하게 만들려고했는데, BEFORE와 AFTER는 모두 같은 방식으로 작동하고 test3Async를 실행하지 않습니다. 누군가 다른 장소에 캐치를 배치하는 주요 차이점을 설명해 줄 수 있습니까?

각 기능 console.log('Running test X')에서 실행 여부를 확인합니다.

이 질문은 내가 게시 한 이전 스레드 때문에 발생합니다 중첩 된 콜백을 약속으로 바꾸는 방법? . 나는 그것이 다른 문제이고 다른 주제를 게시 할 가치가 있다고 생각합니다.



답변

따라서 기본적으로이 둘의 차이점이 무엇인지 묻습니다 ( p이전 코드에서 생성 된 promise는 어디에 있습니까 ).

return p.then(...).catch(...);

return p.catch(...).then(...);

p가 해결하거나 거부 할 때 차이가 있지만 이러한 차이가 중요한지 여부는 .then()또는 .catch()핸들러 내부의 코드가 수행하는 작업에 따라 다릅니다 .

p해결 되면 어떻게 되나요?

첫 번째 체계에서 p해결되면 .then()처리기가 호출됩니다. 해당 .then()핸들러가 값이나 결국 해결되는 다른 promise를 반환하면 .catch()핸들러를 건너 뜁니다. 그러나 .then()핸들러가 결국 거부하는 promise를 던지거나 반환하는 경우 .catch()핸들러는 원래 promise의 거부와 핸들러 p에서 발생하는 오류 모두에 대해 실행됩니다 .then().

두 번째 체계에서는 p해결 될 때 .then()처리기가 호출됩니다. 해당 .then()핸들러가 결국 거부하는 프라 미스를 던지거나 리턴하면 .catch()핸들러가 체인에서 앞에 있기 때문에이를 포착 할 수 없습니다.

그래서 이것이 차이점 # 1입니다. 는 IF .catch()처리기 이후, 그것은 또한 내부 오류를 잡을 수 .then()처리기를.

p거부 하면 어떻게 되나요?

이제 첫 번째 체계에서 promise가 p거부되면 .then()핸들러를 건너 뛰고 .catch()예상대로 핸들러가 호출됩니다. .catch()처리기 에서 수행하는 작업에 따라 최종 결과로 반환되는 내용이 결정됩니다. .catch()핸들러 에서 값을 반환하거나 결국 해결되는 promise를 반환하면 오류를 “처리”하고 정상적으로 반환했기 때문에 promise 체인이 해결 된 상태로 전환됩니다. .catch()핸들러 에서 거부 된 promise를 던지거나 반환 하면 반환 된 promise는 거부 된 상태로 유지됩니다.

두 번째 체계에서 promise가 p거부되면 .catch()핸들러가 호출됩니다. 정상 값이나 결국 .catch()처리기 에서 해결되는 약속을 반환하면 (따라서 오류를 “처리”) promise 체인이 해결 된 상태로 전환되고 .then()이후 처리기 .catch()가 호출됩니다.

이것이 차이점 # 2입니다. 는 IF .catch()핸들러가 전입니다, 그것은 오류를 처리하고 허용 할 수 .then()처리기가 여전히 전화를받을 수 있습니다.

사용시기 :

.catch()원래 프라 미스 p또는 .then()핸들러 에서 오류를 포착 할 수있는 핸들러 하나만 원하는 경우 첫 번째 스킴을 사용하고 거부에서 핸들러를 p건너 뛰어야 .then()합니다.

두 번째 스키마를 사용하면 원래 promise에서 오류를 포착 p하고 (조건에 따라 다름) 약속 체인이 해결 된대로 계속되도록 허용하여 .then()처리기 를 실행 합니다.

다른 옵션

다음 .then()과 같이 전달할 수있는 두 콜백을 모두 사용하는 다른 옵션이 있습니다 .

 p.then(fn1, fn2)

이렇게하면 fn1또는 중 하나만 fn2호출됩니다. 경우에 p결의 한 후 fn1호출됩니다. p거부 하면 fn2호출됩니다. 의 결과 변경은 전화 fn1fn2받을 수 없으며 그 반대도 마찬가지입니다. 따라서 핸들러 자체에서 어떤 일이 발생하는지에 관계없이 두 핸들러 중 하나만 호출되도록하려면 p.then(fn1, fn2).


답변

jfriend00의 대답 은 훌륭하지만 유사한 동기 코드를 추가하는 것이 좋은 생각이라고 생각했습니다.

return p.then(...).catch(...);

동기식과 유사합니다.

try {
  iMightThrow() // like `p`
  then()
} catch (err) {
  handleCatch()
}

iMightThrow()던지지 않으면 then()호출됩니다. 던지면 (또는 then()자체적으로 던지면) handleCatch()호출됩니다. catch블록 then이 호출 여부를 제어하지 않는 방법을 확인하십시오 .

반면에

return p.catch(...).then(...);

동기식과 유사합니다.

try {
  iMightThrow()
} catch (err) {
  handleCatch()
}

then()

이 경우 iMightThrow()던지지 않으면 then()실행됩니다. throw되면 호출 handleCatch()여부를 결정해야 then()합니다. handleCatch()다시 throw되면 then()호출되지 않으므로 예외가 호출자에게 즉시 throw됩니다. handleCatch()문제를 정상적으로 처리 할 수 있으면 then()호출됩니다.


답변