首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用任务单?(fp-ts)

如何使用任务单?(fp-ts)
EN

Stack Overflow用户
提问于 2021-01-07 23:01:14
回答 1查看 2.5K关注 0票数 2
代码语言:javascript
复制
import * as T from 'fp-ts/lib/Task'
import { pipe, flow } from 'fp-ts/lib/function'

const getHello: T.Task<string> = () => new Promise((resolve) => {
  resolve('hello')
})

我理解Task的目的以及为什么它是重要的。问题是,我不知道如何正确地使用它,也不知道如何组合它,真的。

如果我给getHello()打电话,它会给我Promise<pending>

代码语言:javascript
复制
console.log(getHello()) // returns Promise<pending>

然而,如果我这样做:

代码语言:javascript
复制
const run = async () => {
  const hello = await getHello()
  console.log(hello) // prints 'hello'
}

它起作用了。

但这一点:

代码语言:javascript
复制
const waitAndGet = async () => {
  return await getHello()
}

console.log(waitAndGet()) // prints Promise<pending>

不会的。

此外,我怎样才能与它合拍呢?就像这样:

代码语言:javascript
复制
const getHelloAndAddWorld = flow(
  getHello(),
  addAtEnd('world')
)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-07 23:48:13

首先,让我们了解一下Task到底是什么。

代码语言:javascript
复制
export interface Task<A> {
  (): Promise<A>
}

// note that this could also be written as
export type Task<A> = () => Promise<A>

Task只是一个返回Promise的函数,所以在您的示例中,调用getHello将返回一个Promise<string>

console.log(getHello())console.log(Promise.resolve('hello'))是一样的,所以这就是为什么它会记录像Promise {<fulfilled>: "hello"}Promise<pending>之类的东西,或者其他东西而不是hello

代码语言:javascript
复制
// Promise.resolve(foo) is the same as new Promise(resolve => resolve(foo))
const getHello = () => Promise.resolve('hello')
console.log(getHello())

有关承诺的更多信息,我建议阅读在MDN上使用承诺

至于如何与其组合,由于Task是一个Monad,所以可以使用mapapchainapSecond等。

例如,假设addAtEnd是这样定义的:

代码语言:javascript
复制
const addAtEnd = (b: string) => (a: string): string => a + b

您可以通过使用getHello()来使用Task.map

代码语言:javascript
复制
import * as T from 'fp-ts/Task'
import { pipe } from 'fp-ts/function'

// type of map:
// export declare const map: <A, B>(f: (a: A) => B) => (fa: Task<A>) => Task<B>

// Task<string> which, when called, would resolve to 'hello world'
const getHelloAndAddWorld = pipe(
  getHello,
  T.map(addAtEnd(' world'))
)

// same as
const getHelloAndAddWorld = T.map(addAtEnd(' world'))(getHello)

或者,如果您想记录该值,可以使用chainIOKConsole.log

代码语言:javascript
复制
import * as Console from 'fp-ts/Console'

// type of T.chainIOK:
// export declare function chainIOK<A, B>(f: (a: A) => IO<B>): (ma: Task<A>) => Task<B>

// type of Console.log:
// export declare function log(s: unknown): IO<void>

// Note that IO<A> is a function that (usually) does a side-effect and returns A
// (() => A)

// Task<void>
const logHelloAndWorld = pipe(
  getHelloAndAddWorld,
  T.chainIOK(Console.log)
)

// same as
const logHelloAndWorld = pipe(
  getHello,
  T.map(addAtEnd(' world')),
  T.chainIOK(Console.log)
)

要执行Task,只需调用它:

代码语言:javascript
复制
logHelloAndWorld() // logs 'hello world'

对于函子、应用程序和单子的简单介绍,“图中的函子、应用程序和单数”慈祥林的JavaScript版本是一些很好的起点。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65621157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档