将Fluture Future转换为民间故事结果

时间:2018-05-16 03:15:10

标签: javascript node.js folktale fluture

我有以下示例代码来获取uuid:

const Result = require('folktale/result')
const Future = require('fluture')

Future.prototype.flatMap = Future.prototype.chain

const fetch = Future.encaseP(require('node-fetch'))
const message = err => `ERROR: ${err.message}`

function getUuid () {
  return fetch('https://httpbin.org/uuid')
}

const future = getUuid()
  .map(response => {
    const responseJson = response.json.bind(response)
    const getResponseBody = Future.encaseP(responseJson)
    return getResponseBody()
  })
  .map(obj => obj.uuid)

const result = future.fold(Result.Error, Result.Ok).fork(x => x, x => x)
console.log(result) // [Function: Sequence$cancel]
result.map(
  x => {
    return message(x)
  },
  x => {
    console.log(x)
    return x
  }
)

结果不是可映射类型,并在调用result.map时抛出错误:

TypeError: result.map is not a function

2 个答案:

答案 0 :(得分:1)

fork执行future,期望您处理在fork参数中提供的回调中的结果,更重要的是返回cancel函数,而不是下一个Future期望我将.map用于其结果。

将代码更改为:

const cancelToken = future
    .fold(Result.Error, Result.Ok)
    // if you wanna map result, do it here:
    // .map(...)
    .fork( // fork consumes the fluture and ends execution chain
        ok => message(x), 
        err => { console.log(err); }
    );
// call cancelToken() if you want to cancel it

答案 1 :(得分:1)

不可能将Future转换为同步数据结构,因为它将不得不阻塞线程。获得Future结果的唯一方法是提供回调。

在以下行中:

const result = future.fold(Result.Error, Result.Ok).fork(x => x, x => x)

您已经假设您提供给fork的回调的返回值将确定整个表达式的返回值,因此将其分配给result常量。 / p>

当然,问题在于,在完成异步工作之后,这些回调将最终被调用 ,这在以后的JavaScript代码中会出现。这意味着,当其中一个回调运行时,result变量将被分配很长时间并且可能也已读取。

相反,fork返回一个unsubscribe函数。因此,您分配给result的实际值就是该unsubscribe函数。

您可以调用它来向Future发出信号,表示您对最终结果不再感兴趣,从而可以清理Future。


您可以做两件事:

  1. 不要将您的期货转换为结果,而是将结果转换为期货。期货是结果的超集。它们代表成功和失败,以及异步和I / O。由于您的程序是异步的,并且您不能在Node中阻塞线程,因此很可能在程序边缘以Future作为主要类型(类似于以async函数结束的方式)在您使用Promises的入口点)。
  2. 在回调中提供程序的其余部分。您已经fold将拒绝分支划分为Result类型,因此可以安全地使用Fluture的value提供单个回调:

    future.fold(Result.Error, Result.Ok).value(result => result.map(...))