首页 > 解决方案 > 民间故事的未来是为了什么?

问题描述

背景

我正在阅读每一寸文档,并尽可能多地了解 Folktale。最近,我决定试试Future

我们需要未来吗?

现在,虽然我了解and 之间的区别Taskand (支持取消)但我不清楚and之间的区别。PromiseTaskFutureFuturePromise

为什么我要使用 aFuture而不是 a Promise?我会有什么好处?好吧,你可以说:“这样你实际上有一个单子,而不是单子的抱歉借口”。

这本身就是一个很好的论点,但是......记住我总是需要从 Promise 转换为其他东西(到 future )并且Future's API 几乎相同,我不清楚,因为一个新人,我为什么要关心Future

代码示例

假设我有这个函数,其中request是一个发出请求并返回一些结果的函数。

extractRequestInfo是一个从响应对象中提取数据的函数。如果出现故障,我catch会出错并返回一个包含所有数据、badId 和错误的对象。

const requestFruit = request => data =>
    request( data )
        .then( extractRequestInfo )
        .catch( error => ( { badId: prop( [ "Id" ], data ), error } ) );

鉴于这是一个 HTTP 请求,我知道我不需要 a Task,因为我在这里无法取消。所以我的选择是PromiseFuture

问题

  1. 我将如何Future在此示例中使用?
  2. 既然这可能会失败,我也应该使用Result吗?

标签: javascriptfunctional-programmingfolktale

解决方案


引用创建者 Quil 的回应:

Future 解决了与 Promise 相同的问题,因此两者在概念上没有太大区别。不同之处在于他们如何解决问题。

Promise 可以成功或失败。在应用到 promise 的值的任何转换中,同步抛出的错误将被隐式捕获并拒绝该 promise。这在 async/await 中很有趣,因为您可以以类似的方式处理这些错误(同步和异步)——您不需要将每个同步操作都提升为 Promise,因为运行时会为您执行此操作。

这样做的缺点是很容易捕捉到您不打算捕捉的错误,并使您的系统在不一致的状态下运行。我不认为你可以在这里做很多静态分析。

期货没有这个问题,因为没有任何东西被隐含地提升到未来。如果您希望同步操作使用 Future 管道来处理错误,您必须明确地将它们放在那里。这使您可以更好地控制错误处理,并且未捕获的错误仍会按预期使进程崩溃(避免您的程序在您未预测的情况下运行到不一致的内存状态),但是以这种方式编写程序需要更多的努力。

除此之外,如果您考虑 Tasks,Futures 会使用成功案例、失败案例和取消案例对 Task 的最终价值进行建模。Promise 只有一个成功案例和一个失败案例,所以取消被建模为一个特殊的失败值。这稍微改变了处理取消的习惯用法。使用 Promise 的代码可能会在不知道这个特殊的取消值的情况下处理失败,这可能是一个问题,因为在这些转换过程中这个值很容易丢失。

在混合了 Promise 和任务的代码库中,这些问题更加复杂,因为 Promise 所做的隐式提升错误与任务/未来期望的显式提升错误不太兼容(这可能导致像这样的问题:# 163)。与只有承诺或只有任务/未来相比,找到这些错误要困难得多。尚不确定处理这些情况的最佳方法是什么。

对于原始讨论:

https://github.com/origamitower/folktale/issues/200


推荐阅读