将Fluture Future转为folktale Result时遇map调用类型错误
解决Fluture Future转Folktale Result后无法调用map的问题
你的问题出在对Fluture的fork方法理解有误——fork返回的不是Future的最终结果,而是一个用于取消异步操作的函数,这就是为什么你打印result看到的是[Function: Sequence$cancel],自然调用map会抛出TypeError。
错误原因拆解
看你代码里这一段:
const result = future.fold(Result.Error, Result.Ok).fork(x => x, x => x)
Fluture的fold方法确实会把Future转换成一个最终产生Folktale Result的Future,但fork方法的作用是启动这个异步Future,它的两个参数是失败/成功的回调函数,而fork本身的返回值是取消函数,不是回调里的返回值。你直接把这个取消函数赋值给result,当然无法调用Result的map方法。
解决方案:正确处理异步结果
有两种常见的正确处理方式:
方式1:在fork的回调中处理Result
把对Result的map/匹配逻辑放到fork的成功回调里,因为只有在回调中才能拿到真正的Result实例:
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() }) .flatMap(obj => Future.of(obj.uuid)) // 用flatMap扁平化嵌套的Future结构 // 正确使用fork:在回调中拿到真正的Result实例 future.fold(Result.Error, Result.Ok) .fork( err => console.error(message(err)), // 处理失败分支的Error result => { // 成功分支获取Result result.map( err => message(err), uuid => { console.log(uuid) return uuid } ) } )
方式2:将Future转为Promise处理
如果你更习惯Promise的写法,可以用Fluture的promise方法把Future转成Promise,再用then或async/await处理Result:
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() }) .flatMap(obj => Future.of(obj.uuid)) // 转Promise后处理Result future.fold(Result.Error, Result.Ok) .promise() .then(result => { result.map( err => message(err), uuid => { console.log(uuid) return uuid } ) }) .catch(err => console.error(message(err)))
这两种方式都能让你正确拿到Folktale的Result实例,进而正常调用它的map方法。
内容的提问来源于stack exchange,提问作者vamsiampolu
相关产品推荐
相关产品推荐

