자바 스크립트 약속-거부와 던지기
이 주제에 대해 여러 기사를 읽었지만 Promise.reject
오류와 던지기 사이에 차이가 있는지는 분명하지 않습니다 . 예를 들어
Promise.reject 사용
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
return Promise.reject(new PermissionDenied());
}
});
던지기 사용하기
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
throw new PermissionDenied();
}
});
내가 선호 throw
하는 것은 더 짧기 때문에 단순히 사용하는 것이지만 다른 것보다 이점이 있는지 궁금합니다.
하나를 사용하는 것의 장점 throw
은 없지만 작동하지 않는 특정한 경우 가 있습니다. 그러나 이러한 경우는 고칠 수 있습니다.
약속 콜백 내부에 있으면 언제든지을 사용할 수 있습니다 throw
. 그러나 다른 비동기 콜백 인 경우을 사용해야합니다 reject
.
예를 들어, 이것은 catch를 트리거하지 않습니다.
new Promise(function() {
setTimeout(function() {
throw 'or nah';
// return Promise.reject('or nah'); also won't work
}, 1000);
}).catch(function(e) {
console.log(e); // doesn't happen
});
대신에 해결되지 않은 약속과 잡히지 않은 예외가 남게됩니다. 대신을 사용하려는 경우 reject
입니다. 그러나 시간 초과를 약속하여이 문제를 해결할 수 있습니다.
function timeout(duration) { // Thanks joews
return new Promise(function(resolve) {
setTimeout(resolve, duration);
});
}
timeout(1000).then(function() {
throw 'worky!';
// return Promise.reject('worky'); also works
}).catch(function(e) {
console.log(e); // 'worky!'
});
또 다른 중요한 사실이다 reject()
않습 유사한 제어 흐름을 종료 return
문을 수행합니다. 반대로 throw
제어 흐름은 종료됩니다.
예:
new Promise((resolve, reject) => {
throw "err";
console.log("NEVER REACHED");
})
.then(() => console.log("RESOLVED"))
.catch(() => console.log("REJECTED"));
vs
new Promise((resolve, reject) => {
reject(); // resolve() behaves similarly
console.log("ALWAYS REACHED"); // "REJECTED" will print AFTER this
})
.then(() => console.log("RESOLVED"))
.catch(() => console.log("REJECTED"));
예, 가장 큰 차이점은 거부 는 약속이 거부 된 후에 수행되는 콜백 함수이며 throw 는 비동기 적으로 사용할 수 없다는 것입니다. 거부를 사용하도록 선택한 경우 코드는 비동기 방식으로 계속 정상적으로 실행되지만 throw 는 리졸버 기능 완료를 우선 순위로 둡니다 (이 기능은 즉시 실행 됨).
내가 본 문제를 분명히하는 데 도움이되는 예는 다음과 같이 거부로 Timeout 함수를 설정할 수 있다는 것입니다.
new Promise(_, reject) {
setTimeout(reject, 3000);
});
위는 던지기로 쓸 수 없었습니다.
작은 예제에서 구별 할 수없는 차이가 있지만보다 복잡한 비동기 개념을 처리 할 때는 둘 사이의 차이가 극심 할 수 있습니다.
TLDR : 함수는 때때로 약속을 반환하고 때로는 예외를 던질 때 사용하기가 어렵습니다. 비동기 함수를 작성할 때 거부 된 약속을 반환하여 신호 실패를 선호합니다.
귀하의 특정 예는 그들 사이의 중요한 차이점을 모호하게합니다 :
약속 체인 내 에서 오류를 처리하기 때문에 throw 된 예외는 자동으로 거부 된 약속 으로 변환 됩니다. 이것은 왜 그들이 상호 교환 가능한 것처럼 보일 수 있는지 설명 할 수 있습니다.
아래 상황을 고려하십시오.
checkCredentials = () => {
let idToken = localStorage.getItem('some token');
if ( idToken ) {
return fetch(`https://someValidateEndpoint`, {
headers: {
Authorization: `Bearer ${idToken}`
}
})
} else {
throw new Error('No Token Found In Local Storage')
}
}
비동기 및 동기화 오류 사례를 모두 지원해야하기 때문에 이것은 안티 패턴입니다. 다음과 같이 보일 수 있습니다.
try {
function onFulfilled() { ... do the rest of your logic }
function onRejected() { // handle async failure - like network timeout }
checkCredentials(x).then(onFulfilled, onRejected);
} catch (e) {
// Error('No Token Found In Local Storage')
// handle synchronous failure
}
좋지 않으며 여기서 Promise.reject
(전 세계적으로 이용 가능한) 구출의 정확한 위치 와 효과적으로 차별화됩니다 throw
. 리 팩터는 이제 다음과 같습니다.
checkCredentials = () => {
let idToken = localStorage.getItem('some_token');
if (!idToken) {
return Promise.reject('No Token Found In Local Storage')
}
return fetch(`https://someValidateEndpoint`, {
headers: {
Authorization: `Bearer ${idToken}`
}
})
}
이제 catch()
네트워크 장애 및 토큰 부족에 대한 동기 오류 검사에 하나만 사용할 수 있습니다 .
checkCredentials()
.catch((error) => if ( error == 'No Token' ) {
// do no token modal
} else if ( error === 400 ) {
// do not authorized modal. etc.
}
시험해 볼만한 예. throw 대신 거부를 사용하려면 isVersionThrow를 false로 변경하십시오.
const isVersionThrow = true
class TestClass {
async testFunction () {
if (isVersionThrow) {
console.log('Throw version')
throw new Error('Fail!')
} else {
console.log('Reject version')
return new Promise((resolve, reject) => {
reject(new Error('Fail!'))
})
}
}
}
const test = async () => {
const test = new TestClass()
try {
var response = await test.testFunction()
return response
} catch (error) {
console.log('ERROR RETURNED')
throw error
}
}
test()
.then(result => {
console.log('result: ' + result)
})
.catch(error => {
console.log('error: ' + error)
})
참고 URL : https://stackoverflow.com/questions/33445415/javascript-promises-reject-vs-throw
'Programing' 카테고리의 다른 글
AngularJS에서 쿼리 매개 변수를 읽는 가장 간결한 방법은 무엇입니까? (0) | 2020.03.11 |
---|---|
루비에서 열거 형을 구현하는 방법은 무엇입니까? (0) | 2020.03.11 |
GDI +, JPEG 이미지에서 MemoryStream으로 일반 오류가 발생했습니다. (0) | 2020.03.11 |
언제 require ()를 사용해야하고 언제 define ()을 사용해야합니까? (0) | 2020.03.11 |
공유 라이브러리를로드하는 중 Linux 오류 : 공유 객체 파일을 열 수 없습니다 : 해당 파일 또는 디렉토리가 없습니다 (0) | 2020.03.11 |