조기 해결 / 거부 후 귀국해야합니까?

다음 코드가 있다고 가정하십시오.

function divide(numerator, denominator) {
 return new Promise((resolve, reject) => {

  if(denominator === 0){
   reject("Cannot divide by 0");
   return; //superfluous?
  }

  resolve(numerator / denominator);

 });
}

나의 목표가 reject일찍 퇴장하는 데 사용된다면 , return바로 후에도 습관을 섭취 해야 합니까?



답변

return목적은 후에 제거 기능의 실행을 종료하고, 그 후, 코드의 실행을 방지하기위한 것이다.

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {

    if (denominator === 0) {
      reject("Cannot divide by 0");
      return; // The function execution ends here 
    }

    resolve(numerator / denominator);
  });
}

이 경우 resolve(numerator / denominator);엄격하게 필요하지 않은 실행을 방지 합니다. 그러나 향후 가능한 트랩을 방지하기 위해 실행을 종료하는 것이 여전히 바람직합니다. 또한 불필요하게 코드 실행을 방지하는 것이 좋습니다.

배경

약속은 3 가지 상태 중 하나 일 수 있습니다.

  1. 보류 중-초기 상태 보류 상태에서 다른 상태 중 하나로 이동할 수 있습니다
  2. 이행-성공적인 운영
  3. 거부 됨-작업 실패

약속이 이행되거나 거절 될 때,이 상태는 무기한 (정착)으로 유지됩니다. 따라서 약속 된 약속을 거부하거나 거부 된 약속을 이행해도 효과가 없습니다.

이 예제 스 니펫은 약속이 거부 된 후에도 이행되었지만 거부 된 상태임을 보여줍니다.

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {
    if (denominator === 0) {
      reject("Cannot divide by 0");
    }

    resolve(numerator / denominator);
  });
}

divide(5,0)
  .then((result) => console.log('result: ', result))
  .catch((error) => console.log('error: ', error));

그렇다면 왜 돌아와야합니까?

확정 된 약속 상태를 변경할 수는 없지만 거부하거나 해결해도 나머지 기능의 실행은 중지되지 않습니다. 이 함수에는 혼란스러운 결과를 생성하는 코드가 포함될 수 있습니다. 예를 들면 다음과 같습니다.

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {
    if (denominator === 0) {
      reject("Cannot divide by 0");
    }
    
    console.log('operation succeeded');

    resolve(numerator / denominator);
  });
}

divide(5, 0)
  .then((result) => console.log('result: ', result))
  .catch((error) => console.log('error: ', error));

함수에 지금 그러한 코드가 포함되어 있지 않더라도 앞으로 가능한 함정이 생길 수 있습니다. 향후 리 팩터는 약속이 거부 된 후에도 코드가 여전히 실행되어 디버그하기 어렵다는 사실을 무시할 수 있습니다.

해결 / 거부 후 실행 중지 :

이것은 표준 JS 제어 흐름입니다.

  • resolve/ reject다음에 반환
  • 로 돌아 가기 resolve/ reject– 콜백의 반환 값이 무시되기 때문에, 우리는이 / 해결 문을 거부 반환하여 선을 절약 할 수 있습니다 :
  • if / else 블록 사용 :

return코드가 더 평평 하므로 옵션 중 하나를 사용하는 것을 선호합니다 .


답변

또는 당신의 차 한잔하지 않을 수 있습니다 일반적인 관용구,의 결합하는 것입니다 return과를 reject함수의 나머지 부분이 포함되도록, 동시에 함수의 약속 종료를 거부하려면, resolve실행되지 않습니다. 이 스타일이 마음에 들면 코드를 좀 더 간결하게 만들 수 있습니다.

function divide(numerator, denominator) {
  return new Promise((resolve, reject) => {
    if (denominator === 0) return reject("Cannot divide by 0");
                           ^^^^^^^^^^^^^^
    resolve(numerator / denominator);
  });
}

약속 생성자는 어떤 리턴 값으로 아무것도하지 않으며, 어떠한 경우에도 때문에 잘 작동 resolve하고 reject반환 아무것도.

다른 답변에 표시된 콜백 스타일과 동일한 관용구를 사용할 수 있습니다.

function divide(nom, denom, cb){
  if(denom === 0) return cb(Error("Cannot divide by zero"));
                  ^^^^^^^^^
  cb(null, nom / denom);
} 

다시 말하지만, 호출하는 사람 divide은 아무것도 리턴하지 않고 리턴 값으로 아무것도하지 않기 때문에 제대로 작동합니다.


답변

기술적으로 여기에서는 필요하지 않습니다. 1- 약속은 독점적으로 한 번만 해결 하거나 거부 할 수 있기 때문 입니다. 첫 번째 약속 결과가 승리하고 모든 후속 결과는 무시됩니다. 이것은 노드 스타일 콜백 과 다릅니다 .

즉 , 더 이상 비동기 / 지연된 처리가 없기 때문에 실제로는 실제로이 경우에는 정확히 하나가 호출되도록하는 것이 좋습니다 . “조기 반환”결정 은 작업이 완료되었을 때 기능을 종료하는 것과 관련이 있습니다.

적절한 시간에 돌아 오면 (또는 “다른”경우의 실행을 피하기 위해 조건부 사용) 실수로 코드를 유효하지 않은 상태로 실행하거나 원하지 않는 부작용을 수행 할 가능성을 줄입니다. 따라서 코드가 ‘예기치 않게 중단되는’경향이 줄어 듭니다.


1기술 답변은 이 경우 “반환”후의 코드를 생략해도 부작용이 발생하지 않는다는 사실에 달려 있습니다. JavaScript는 행복하게 0으로 나누고 + Infinity / -Infinity 또는 NaN을 반환합니다.


답변

해결 / 거부 후에 “반환”하지 않으면 페이지 리디렉션과 같은 나쁜 일이 발생했을 수 있습니다. 출처 : 나는 이것에 부딪쳤다.


답변

Ori의 답변은 이미 필요 return하지는 않지만 좋은 방법이라고 설명합니다. promise 생성자는 안전하게 던져 질 수 있으므로 나중에 경로에서 전달 된 예외를 무시합니다. 본질적으로 쉽게 관찰 할 수없는 부작용이 있습니다.

참고 return초기 보내고하는 콜백도 매우 일반적입니다 :

function divide(nom, denom, cb){
     if(denom === 0){
         cb(Error("Cannot divide by zero");
         return; // unlike with promises, missing the return here is a mistake
     }
     cb(null, nom / denom); // this will divide by zero. Since it's a callback.
} 

따라서 약속하는 것이 좋지만 콜백 이 필요합니다 . 코드에 대한 참고 사항 :

  • 유스 케이스는 가상이므로 실제로는 동기 조치와 함께 약속을 사용하지 마십시오.
  • 약속 생성자 반환 값을 무시 합니다. 정의되지 않은 값을 반환하면 반환되는 실수에 대해 경고하는 경우 일부 라이브러리가 경고합니다. 대부분은 영리하지 않습니다.
  • 약속 생성자는 안전하게 던져져 예외를 거부로 변환하지만 다른 사람들이 지적했듯이 약속은 한 번 해결됩니다.

답변

대부분의 경우 매개 변수를 별도로 확인하고 Promise.reject (reason) 으로 거부 된 약속을 즉시 반환 할 수 있습니다.

function divide2(numerator, denominator) {
  if (denominator === 0) {
    return Promise.reject("Cannot divide by 0");
  }

  return new Promise((resolve, reject) => {
    resolve(numerator / denominator);
  });
}


divide2(4, 0).then((result) => console.log(result), (error) => console.log(error));


답변