假设我有一些异步函数,它从 api 获取并返回一个任务(为简单起见,我提供了一个基本的异步任务:
const someAsyncFunction = taskEither.fromPredicate(
(value: number) => value < 12,
(value: number) => new Error("value was greater than 12")
)
然后我想向哨兵报告错误(如果存在),但是,我希望注入默认值并继续下游执行
const reportError = (error: Error) => console.log(error.message)
type ExceptionHandler = typeof reportError
const unwrapAndReportError = <R>(captureFunction: ExceptionHandler) => (
def: R
) => (inputEither: taskEither.TaskEither<Error, R>): R =>
E.getOrElse((err: Error) => {
captureFunction(err)
return def
})(inputEither)
const runAsyncFunctionThenUnwrapAndReport = flow(
someAsyncFunction,
unwrapAndReportError(reportError)("potato")
)
此代码无法通过以下方式进行类型检查:
Argument of type 'TaskEither<Error, R>' is not assignable to parameter of type 'Either<Error, R>'
完全可运行的示例:https://codesandbox.io/s/fp-ts-playground-forked-dy2xyz?file=/src/index.ts:0-722
我的问题是,使用fp-ts如何实现这种效果?这里推荐的模式是什么(以及如何对其进行类型检查)。
看起来你已经很接近了,
getOrElse
应该可以工作,尽管我认为你是从Either
模块导入的。将其替换为来自 TaskEither
模块的导入。另外,使用 pipe
更为惯用,因此您可以先提供任务任一参数。
也许是这样的?
import * as TE from "fp-ts/lib/TaskEither"
import * as T from "fp-ts/lib/Task"
import { pipe } from "fp-ts/lib/function"
const someAsyncFunction = TE.fromPredicate(
(value: number) => value < 12,
(value: number) => new Error("value was greater than 12")
)
const reportError = (error: Error) => console.log(error.message)
type ExceptionHandler = typeof reportError
const unwrapAndReportError = <R>(captureFunction: ExceptionHandler) => (
def: R
) => (inputEither: TE.TaskEither<Error, R>): Promise<R> =>
pipe(
inputEither,
TE.getOrElse(
(error) => {
captureFunction(error)
return T.of(def)
},
),
)()
const runAsyncFunctionThenUnwrapAndReport = flow(
someAsyncFunction,
unwrapAndReportError(reportError)("potato")
)