슈뢰딩거의 기능
Promises and
throw
considered harmful
예를 들어 아래 코드를 보자
function createUser(email: string): User {
if (users.includes(email)) {
throw new Error(`User with email ${email} already exists`)
}
...
return newUser;
}
또는 비동기 버전
function createUser(email: string): Promise<User> {
return new Promise((resolve, reject) => {
if (users.includes(email)) {
throw new Error(`User with email ${email} already exists`)
}
...
return newUser;
})
}
try {
const result = createUser('email');
...
} catch (error /* error is not typed */) {
...
}
이러한 함수를 호출하는 사람이 함수를 호출하고 런타임에 결과를 확인하지 않고는 함수 호출로 인해 오류가 발생할 수 있고 예상되는 오류 유형을 알 수 있는 방법이 없습니다. 또는 특히 타사 라이브러리를 다룰 때 소스 코드를 검사합니다.
그렇기 때문에 슈뢰딩거의 함수와 같은 함수를 호출합니다. 함수를 호출하거나 검사하기 전에는 함수가 오류인지 아닌지 알 수 없습니다.
I try to avoid directly returning promises for async operations (most especially async operations that may fail), because promises can reject without any indication what the error will be and are hard to
type
the error value.
그래서 제가 따르는 원칙은 약속을 절대 거부하거나 오류를 던지지 않는 것입니다. 누군가는 "그러나 그것들은 타당한 이유로 JavaScript에 추가되었습니다"라고 말할 수 있습니다. 예, 그러나 그들은 또한 코드를 예측할 수 없게 만들고 검사를 입력하기 어렵게 만듭니다. Typescript 사용자의 경우 유형 캐스팅 및 if 문을 사용하여 오류 유형을 확인해야 합니다.
해결책
내가 취하는 접근법은
Result
또는 Err
결과의 두 가지 유형 중 하나일 수 있는 Ok
를 반환하는 것입니다. 기본적으로 약속은 Err
또는 Ok
값으로 해결됩니다. 예를 들어type Err<T> = { _tag: "Err"; value: T };
type Ok<T> = { _tag: "Ok"; value: T };
type Result<E, A> = Err<E> | Ok<A>;
우리는
Result
유형을 Err
및 Ok
의 합집합으로 선언했습니다. 예를 들어 다음과 같이 작성할 수 있습니다.try {
let file = await readFile(...);
return {_tag: "Ok", value: file}
} catch (err) {
return {_tag: "Err", value: err}
}
이제 비동기 작업에 대해 완전히 형식화된 반환 값이 있습니다. 이 함수를 호출하면 다음을 얻을 수 있습니다.
let result = ... // {_tag: "Err", value: ...} | {_tag: "Ok", value: ...}
if (result._tag === "Err") {
// value is of whatever type we defined as error
}
이제 이전에 본 함수를 다시 작성해 보겠습니다.
function createUser(email: string): Result<Error, User> {
if (users.includes(email)) {
return {_tag: "Err", value: new Error(`User with email ${email} already exists`)}
}
...
return {_tag: "Ok", value: newUser};
}
...
그리고 결과 유형을 구별하는 데 도움이 되는 일부 유틸리티 기능
function isErr<E, A>(result: Result<E, A>): result is Err<E> {
return result._tag === "Err";
}
function isOk<E, A>(result: Result<E, A>): result is Ok<A> {
return result._tag === "Ok";
}
마지막으로 함수를 호출합니다.
const result = createUser("email");
if (isErr(result)) {
console.log(result.value); // Error()
}
// our result is `Ok` here
console.log(result.value); // User
이것은 함수형 프로그래밍에서
Either
또는 Maybe
라고 불리는 것에 대한 빠른 실행입니다. 이와 같은 다른 아이디어에 대해 자세히 알아보려면 fp-ts을 확인하십시오.
Reference
이 문제에 관하여(슈뢰딩거의 기능), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/joshuaamaju/schrodingers-function-3nc7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)