【问题标题】:What is the inverse of a promise?承诺的反义词是什么?
【发布时间】:2014-11-22 22:24:07
【问题描述】:

promise 表示将来可能可用(或不可用)的值。

我正在寻找的是一种数据类型,它表示将来可能变得不可用(可能由于错误)的可用值:

Promise a b = TransitionFromTo<PENDING, Either<value a, error b>>
??? a       = TransitionFromTo<value a, Either<ENDED, FAILED>> or
??? a b     = TransitionFromTo<value a, Either<ENDED, error b>>

是否已经探索过这样的概念(或类似概念)?有没有现成的语义或常用习语?

例如,它可能表示将关闭的打开的数据库连接。我的特定用例将表示一个“可变”,即 FRP 中的可变大小、类似集合的集合作为此类“结束值”的流——当事件发生时,值被添加到集合中,当值“结束”时" 它被删除了。

我觉得将其表示为 Signal&lt;Option&lt;value&gt;&gt;{data = value, ended = Promise&lt;null&gt;} 并不完全匹配 - 第一种情况不包括保证值最终稳定为 Nothing 而第二种情况有 data字段结束后仍可访问。

【问题讨论】:

  • 您关闭数据库连接的用例似乎只是另一个未来价值(重要的不是价值,而是实现的事实)所以为什么不能用常规旧的来表示承诺?
  • @torazaburo:是的,这就是我对{data = value, ended = Promise&lt;null&gt;} 的意思(事实上,这就是我目前实现它的方式)。但是,感觉不对,因为data - 连接 - 始终可以访问,并且因为 promise 不代表值。
  • 我远不是任何类型的 Promise 专家,但在我看来,Promise 不需要 具有值,实际上通常会忽略该值。值不能被认为是一种细节,关于分辨率的附加信息吗?对我来说,忽略值的承诺没有任何代码气味。
  • @torazaburo:是的,没错,有一些用例忽略了价值,只是对时间链感兴趣;对于这些有时会创建不具有价值的承诺。这可能确实用于该类型的实现,但目前我正在寻找这种(抽象)数据结构的名称,它也带有“结算前”值。
  • 首先想到的是弱引用,它可以用来访问一个值,直到不能再访问为止。

标签: scala haskell language-agnostic promise frp


【解决方案1】:

简而言之 - 可以使用异步生成器进行建模。

在数据库连接示例中,从概念上讲,您有一个数据库连接序列,每次访问值时,您都会从序列(连接)中产生(可能异步)一个值。产生可以是异步的,值本身也可能是异步的。该序列可能会结束(使其不再可用)或者它可能总是产生结果 - 它可能保持未决状态并且不再产生另一个连接。

值得一提的是,异步生成器是您所追求的类型的巨大超集 - 它更具表现力,而不是直接的逆。

在长 - 逆如何?

你可以用几种不同的方式来反转一个承诺。

promise 是一个 singular temporal getter。那就是它拥有以下内容:

  • 它代表一个单个值。
  • 它的值是temporal(即取决于时间)。
  • 这是一个吸气剂

引用 Kris 关于承诺的时间性的工作

观察者可以订阅最终看到一个承诺的价值。他们可以在承诺具有价值之前或之后执行此操作。任意数量的观察者都可以订阅多次,任何一个观察者可以多次订阅同一个 Promise.... Promise 是广播。任何消费者都不能干涉另一个消费者的法律使得承诺不可能中止正在进行的工作。承诺代表一个结果,而不是导致该结果的工作。

promise 在这些方面的反面是不同的。

  • Deferred 是一个奇异的时间设置器。它是 Promise 的对偶,它允许设置一个值,类似于 Promise 允许获取它的方式。

  • Reader(通常称为 observable)是 promise 的多个版本,以及 iterable 的临时版本。它代表了暂时到来的多个值。这就像一个可以改变其价值的承诺。

  • Value,最常用和最原始的东西之一是 Promise 的同步版本。

如果您想要的东西与所有三个承诺都不同 - 您需要更高级的东西。 Generator 在这方面是 promise 的反面,它是一个空间的、多值的 setter。在所有这些方面,它都与承诺背道而驰。

但是,您所说的是在这两个方面都是异步的,您想要的是可用/不可用且改变价值的东西。这是一个异步生成器,这里使用的更复杂的类型之一。

您的类型需要类似于两次异步的生成器,一次是获取下一个值,一次是获取值本身,我问过a similar C# question here。这里是an interesting talk and lecture about it

基本上,您需要一个其值 next() 是异步的生成器。它相当复杂,而且很少能正确建模(例如 - 无限滚动,其中滚动和内容都是异步的)。

从某种意义上说,序列结束表示您的值“不再可用”,而生成下一个实例的序列表示您的信号暂时不再可用。

我也推荐Erik Meijer's talkKris Kowal's GTOR 关于这个主题。

【讨论】:

  • 我想我想反转承诺的时间部分——这就像将它从“有价值”倒退到“待定/不可用”。它仍然应该是单个值,并且是一个 getter(结构的创建者设置值并确定何时结束它)。
  • 我看到你对数据库连接序列做了什么(我读过 GTOR 并发现这个异步+异步生成器的概念非常有趣)。然而,next 事件应该使之前的值不可用,它应该一直持续到它决定自己结束 - 想想池连接。我的实际用例是(反应性)子节点的集合,这些子节点被创建为流事件(可以说是由生成器创建),然后一旦它们“结束”就应该从它们的父节点中删除。
  • @Bergi 我记得dl.acm.org/citation.cfm?id=54016(原始承诺文件)中的一些相关内容,但我无法在这里打开它,因为我这里没有我的学术VPN。所以我会检查我什么时候在大学 - 如果你可以访问资源 - 看看:) 编辑:我做了一些相当粗鲁的事情,也许它会结出果实,我们将不得不拭目以待.
  • 是的,幸运的是我不需要我的大学 VPN 来访问它 :-) 你知道我到底应该寻找什么吗? PS:你认为什么不礼貌?
  • @Bergi 你能come here real quick?
【解决方案2】:

您在标签中提到了“scala”,因此:在 jvm 上,它可以作为软/弱参考来完成。您可以将该概念移植到不同的技术,但必须自己进行内存管理。但它更适合处理单个值而不是流

【讨论】:

  • 弱引用不是逆向承诺。他想要的是一个值(我们称之为 Expirable),您可以像 Scala Future 一样解包它,并且如果您足够快地附加处理程序,则该值可以“过期”,此时您所有未来的解包尝试将永远挂起。
【解决方案3】:

promise 是一个有序的三元组:

Time -> Notification -> Value

它的逆也必须是有序三元组:

Value -> Notification -> Time

但是,您不希望在值开始衰减时收到通知,即立即;相反,您希望在值 衰减时收到通知。

Value -> Time -> Notification

通知带有Dispose语义。实际上,如果定义为IDisposable&lt;T&gt;,它与IDisposable 非常相似。

public interface IDisposable<T out>
{
  T Value { get; }
  IDisposable Subscribe(Action disposedAction);
  void Dispose();  // Not entirely necessary, perhaps.
}

它看起来像是 Task&lt;T&gt;IObservable&lt;T&gt; 的科学怪人混合体。

IDisposable 的异步对偶可能吗?

【讨论】:

  • disposable 的异步对偶是一件令人着迷的事情,我们在 Bluebird 中讨论它的 API 时获得了很多乐趣。我不认为这是它。 Kris 提到,weakrefs 或 promises 作为真正的代理是相关的。
  • @BenjaminGruenbaum 是的,我想这不是双重的。对偶会将 Value 反转为 setter;例如,void(T next)。这更像是 IObserver。奇怪。
  • 双重将被推迟:)
  • 你使用 C# 的符号,所以让我试试这个:在这种情况下,延迟是承诺,因为任务完成源是任务。
  • 没关系,它真的与语言无关,它有多种语言的许多名称 :)
猜你喜欢
  • 2011-01-04
  • 2014-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多