作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 FP-TS 的新手,但仍然不太明白如何使用 TaskEither
.我正在尝试异步读取文件,然后使用 yaml-parse-promise 解析结果字符串。
==编辑==
我用文件的完整内容更新了代码以提供更多上下文并应用了 MnZrK 提供的一些建议。抱歉,我还是 FP-TS 的新手,我仍在努力使类型匹配。
现在我的错误是 map(printConfig)
线:
Argument of type '<E>(fa: TaskEither<E, AppConfig>) => TaskEither<E, AppConfig>' is not assignable to parameter of type '(a: TaskEither<unknown, AppConfig>) => Either<unknown, Task<any>>'.
Type 'TaskEither<unknown, AppConfig>' is not assignable to type 'Either<unknown, Task<any>>'.
Type 'TaskEither<unknown, AppConfig>' is missing the following properties from type 'Right<Task<any>>': _tag, rightts(2345)
import { pipe } from 'fp-ts/lib/pipeable'
import { TaskEither, tryCatch, chain, map, getOrElse } from "fp-ts/lib/TaskEither";
import * as T from 'fp-ts/lib/Task';
import { promises as fsPromises } from 'fs';
const yamlPromise = require('js-yaml-promise');
// const path = require('path');
export interface AppConfig {
service: {
interface: string
port: number
};
}
function readFileAsyncAsTaskEither(path: string): TaskEither<unknown, string> {
return tryCatch(() => fsPromises.readFile(path, 'utf8'), e => e)
}
function readYamlAsTaskEither(content: string): TaskEither<unknown, AppConfig> {
return tryCatch(() => yamlPromise.safeLoad(content), e => e)
}
// function getConf(filePath:string){
// return pipe(
// readFileAsyncAsTaskEither(filePath)()).then(
// file=>pipe(file,foldE(
// e=>left(e),
// r=>right(readYamlAsTaskEither(r)().then(yaml=>
// pipe(yaml,foldE(
// e=>left(e),
// c=>right(c)
// ))
// ).catch(e=>left(e)))
// ))
// ).catch(e=>left(e))
// }
function getConf(filePath: string): TaskEither<unknown, AppConfig> {
return pipe(
readFileAsyncAsTaskEither(filePath),
chain(readYamlAsTaskEither)
)
}
function printConfig(config: AppConfig): AppConfig {
console.log("AppConfig is: ", config);
return config;
}
async function main(filePath: string): Promise<void> {
const program: T.Task<void> = pipe(
getConf(filePath),
map(printConfig),
getOrElse(e => {
return T.of(undefined);
})
);
await program();
}
main('./app-config.yaml')
{ _tag: 'Right', right: Promise { <pending> } }
{ service: { interface: '127.0.0.1', port: 9090 } }
最佳答案
所有这些 e=>left(e)
和 .catch(e=>left(e))
是不必要的。
你的第二种方法更惯用。
// convert nodejs-callback-style function to function returning TaskEither
const readFile = taskify(fs.readFile);
// I don't think there is `taskify` alternative for Promise-returning functions but you can write it yourself quite easily
const readYamlAsTaskEither = r => tryCatch(() => readYaml(r), e => e);
function getConf(filePath: string): TaskEither<unknown, AppConfig> {
return pipe(
readFile(path.resolve(filePath)),
chain(readYamlAsTaskEither)
);
}
getConf
返回
TaskEither<unknown, AppConfig>
这实际上是一个
() => Promise<Either<unknown, AppConfig>>
.如果您有比
unknown
更具体的错误类型,然后改用它。
map
组合其他需要对配置进行的操作。或
chain
(即打印到控制台),然后应用一些错误处理来摆脱
Either
部分并最终获得
Task
(实际上只是懒惰
() => Promise
):
import * as T from 'fp-ts/lib/Task';
function printConfig(config: AppConfig): AppConfig {
console.log("AppConfig is", config);
return config;
}
function doSomethingElseWithYourConfig(config: AppConfig): TaskEither<unknown, void> {
// ...
}
async function main(filePath: string): Promise<void> {
const program: T.Task<void> = pipe(
getConf(filePath),
map(printConfig),
chain(doSomethingElseWithYourConfig),
// getting rid of `Either` by using `getOrElse` or `fold`
getOrElse(e => {
// error handling (putting it to the console, sending to sentry.io, whatever is needed for you app)
// ...
return T.of(undefined);
})
);
await program();
}
关于fp-ts - (已解决) 如何在 FP-TS 中链接依赖的 TaskEither 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57316857/
我是一名优秀的程序员,十分优秀!