如何让Monads了解异步函数(Promises / Future)

时间:2016-12-14 21:45:16

标签: javascript functional-programming ramda.js

我正在尝试使用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

问题是这个操作是Async,我不知道如何让我的Either Monad处理它并处理它。

关于如何让Monad在操作中意识到Promise的任何想法?

1 个答案:

答案 0 :(得分:1)

正如您所看到的,Either类型只能表示已经实现的值,而异步操作表示将来可以评估的内容。

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

如果您对Promise的{​​{1}}类似的内容感兴趣Either(并且也遵循Fantasy Land规范),那么您可能希望看一下在其中一个Future实施中,例如Fluture

e.g。

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))