在fp-ts中链接一些异步任务,以保留每个任务的结果

时间:2019-10-25 14:17:31

标签: typescript fp-ts

在fp-ts中,我试图将一些可能失败的异步任务与TaskEither链接在一起,但是我需要在链的后面使用中间任务的结果。

在此示例中:

const getFoo = (a: string): Promise<Foo> => {};
const getBar = (foo: Foo): Promise<Bar> => {};
const mkFooBar = (foo: Foo, bar: Bar): Promise<FooBar> => {};

const async main1: Promise<FooBar> => {
  const a = "a";
  const foo = await getFoo(a);
  const bar = await getBar(foo);
  const fooBar = await mkFooBar(foo, bar);

  return Promise.resolve(fooBar);
};

const main2: Promise<FooBar> => {
  const a = "a";

  return pipe(
    TE.tryCatch(() => getFoo(a), e => e),
    TE.chain(foo => TE.tryCatch(() => getBar(foo), e => e)),
    TE.chain(bar => TE.tryCatch(() => mkFooBar(??, bar), e => e))
  );
};

main1函数是此问题的async/await样式解决方案。我想做的是以fp-ts chain样式模拟类似的内容。 main2是我的尝试。

由于async/await版本将所有中间结果引入了本地范围(即foobar),因此很容易调用mkFooBar,这取决于这两个结果

但是在fp-ts版本中,中间结果被困在每个任务的范围内。

我认为使该版本工作的唯一方法是使异步函数本身(即getFoogetBar返回其参数,或者也许TaskEither包装器返回了参数,以便可以将其传递给链中的下一个函数。

这将是正确的方法吗?还是有一个更简单的版本更类似于async/await版本?

1 个答案:

答案 0 :(得分:0)

根据在以下计算中需要访问中间结果的次数,我建议您使用Do from fp-ts-contrib(Haskell do符号的近似值),或通过手动{ {1}} ping。

给出:

map

import * as TE from "fp-ts/lib/TaskEither"; declare function getFoo(a: string): TE.TaskEither<unknown, Foo>; declare function getBar(foo: Foo): TE.TaskEither<unknown, Bar>; declare function mkFooBar(foo: Foo, bar: Bar): TE.TaskEither<unknown, FooBar>; 的示例:

Do

手动映射示例:

import { Do } from "fp-ts-contrib/lib/Do";

function main2(): TE.TaskEither<unknown, FooBar> {
  return Do(TE.taskEither)
    .bind("foo", getFoo("a"))
    .bindL("bar", ({ foo }) => getBar(foo))
    .bindL("fooBar", ({ foo, bar }) => mkFooBar(foo, bar))
    .return(({ fooBar }) => fooBar);
}