【问题标题】:How to make Either Monads be aware of of Async functions(Promises/Future)如何让 Either Monads 了解异步函数(Promises/Future)
【发布时间】:2016-12-14 21:45:15
【问题描述】:

我正在尝试使用 Either Monad 来传递我的数据,问题是我无法弄清楚如何让我的 Monad 了解异步操作

这就是我所拥有的

let processData = Either.either(_sendError, _sendResponse)

processData(_getDataGeneric(queryResult)
    .chain(_findDevice)
    .chain(_processRequest)
);

queryResult 是我从数据库本身获取的。

问题是获取结果只是在管道的中间。 我想要的是这个

ValidateUserInput -> GetDataFromDB -> ProcessData

processAll(_fetchFromDB(userId)
    .getDataGeneric
    .chain(_findDevice)
    .chain(_processRequest))


//_fetchFromDB , Mongoose Query
 function _fetchFromDB(userId){
        return myModel.findOne({id:userId}).exec()
                                  .then(function(result){
                                     return Right(result)
                                }).catch((err)=>Left(err))
  }

如果结果从 DB 中有效,它将返回一个 Right 实例,如果有任何类型的错误,它将返回 Left

问题是这个操作是异步的,我不确定如何让我的 Either Monad 来处理它。

关于如何让我的 Monad 在其操作中了解 Promise 的任何想法?

【问题讨论】:

  • Model.findOne() 行之前是否有返回关键字?

标签: javascript functional-programming ramda.js


【解决方案1】:

如您所见,Either 类型只能表示已经实现的值,而异步操作表示将来可能会评估的值。

Promise 已经结合了Either 的行为,表示错误值和成功值的可能性。它还通过允许then 返回另一个Promise 实例来捕获单子样式的操作链接行为。

如果您对类似于Promise 的东西感兴趣,它的行为更接近Either(并且也遵循Fantasy Land 规范),那么您可能想查看Future 实现之一比如Fluture

例如

import Future from 'fluture';

const processAll = Future.fork(_sendError, _sendResponse);

const _fetchFromDB =
  Future.fromPromise(userId => myModel.findOne({ id: userId }).exec())

processAll(_fetchFromDB(userId)
  .chain(getDataGeneric)
  .chain(_findDevice)
  .chain(_processRequest))

【讨论】:

  • 啊,我明白了!这就是我怀疑发生的事情。我理解承诺非常类似于 Either 类型,具有拒绝(左)和解决(右)行为。我真正想做的是整合错误处理。例如,将给定承诺的右侧传递到任一链的右侧,并处理给定的数据。如果发生故障,我真的很关心承诺的 Catch 部分,我想把它作为我的错误处理流程的一部分。否则,我需要处理 Either 函数管道,以及错误的 promise.catch 部分。有没有更好的办法?
  • 看来fluture可以与promise规范交互。有没有办法让我以同样的方式使用来自 ramda Fantasy Land 的 Future?
  • 如果你想使用 Ramda Fantasy 创建一个fromPromise 函数,它看起来像fromPromise = fn => (...args) => Future((rej, res) => fn(...args).then(res, rej))
  • 对于这种fluture方法,应该如何实现null处理。我会想象使用 Monad,但它如何适合上面的代码?
猜你喜欢
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 2020-12-25
  • 2016-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多