【问题标题】:execute Fluture task with Sancuary Either使用 Sancuary Either 执行 Fluture 任务
【发布时间】:2019-11-05 07:19:23
【问题描述】:

我有这样的管道

const asyncFn = (x) => {
    return Future.tryP(() => Promise.resolve(x + ' str2'))
};

const pipeResult = S.pipe([
    x => S.Right(x + " str1"), // some validation function
    S.map(asyncFn),
])("X");

pipeResult.fork(console.error, console.log);

我想在asyncFn 中做一些异步操作。 问题是当我有 Right 作为输入时,我可以再分叉它。

当我登录 pipeResult 时,我看到了:

Right (tryP(() => Promise.resolve(x + ' str2')))

我该怎么做?

【问题讨论】:

    标签: javascript functional-programming sanctuary fluture


    【解决方案1】:

    Either a bFuture a b 都能够表达失败/成功。在处理异步计算时,通常最好使用Future a b 而不是Future a (Either b c)。更简单、更扁平的类型需要更少的映射:S.map (f) 而不是S.map (S.map (f))。另一个优点是错误值总是在同一个地方,而Future a (Either b c)ab 都表示计算失败。

    不过,我们可能已经有了一个返回 any 的验证函数。例如:

    //    validateEmail :: String -> Either String String
    const validateEmail = s =>
      s.includes ('@') ? S.Right (S.trim (s)) : S.Left ('Invalid email address');
    

    如果我们有一个fut 类型为Future String String 的值,我们如何验证fut 可能包含的电子邮件地址?首先要尝试的总是S.map

    S.map (validateEmail) (fut) :: Future String (Either String String)
    

    最好避免这种嵌套。为此,我们首先需要定义一个从Either a bFuture a b 的函数:

    //    eitherToFuture :: Either a b -> Future a b
    const eitherToFuture = S.either (Future.reject) (Future.resolve);
    

    我们现在可以将一个返回要么返回的函数转换为返回未来的函数:

    S.compose (eitherToFuture) (validateEmail) :: String -> Future String String
    

    让我们回顾一下我们对S.map的使用:

    S.map (S.compose (eitherToFuture) (validateEmail)) (fut) :: Future String (Future String String)
    

    我们仍然有嵌套,但现在内部和外部类型都是Future String _。这意味着我们可以将S.map 替换为S.chain 以避免引入嵌套:

    S.chain (S.compose (eitherToFuture) (validateEmail)) (fut) :: Future String String
    

    【讨论】:

    • eitherToFuture 辅助函数是我正在寻找的。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2014-02-14
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多