【问题标题】:Cope with Bacon.js's side effects应对 Bacon.js 的副作用
【发布时间】:2014-11-10 19:12:17
【问题描述】:

我是 Bacon.js 的新手,通常用 Haskell 编写程序。 根据我使用 Haskell 的经验,我想将 Bacon.js 中的一些情况描述为纯函数式的方法。

这是一个示例情况。

  • triggerStream 是源流。
  • triggerStream 的事件发生时,resultStream 会尝试 ajax 访问。
  • resultStream2 在完成 resultStream 的 ajax 访问后也会尝试 ajax 访问。

这是我的方法:

### =======
# Streams
# ======= ###
triggerStream = () ->
  Bacon.fromArray([1,2,3])

resultStream = 
  triggerStream()
    .flatMap((n) -> Bacon.fromPromise($.ajax(toAjax n)))
    .zip(triggerStream(), (r,t) ->
      {result: r, trigger: t}

resultStream2 =
  resultStream     # (*)
    .flatMap((o) -> Bacon.fromPromise($.ajax(toAjax2 o)))
    .zip(resultStream, (r2,r1) ->
      {result: r2, trigger: r1.trigger}

### =======
# Assignments
# ======= ###

triggerStream()
  .onValue(beforeAjax1) # (a)
resultStream
  .onValue(afterAjax1)  # (b)
resultStream2
  .onValue(afterAjax2)  # (c)

(a) 支持在每个触发事件之后执行,即在resultStream 的ajax 访问之前执行。

(b) 支持在resultStream 的 ajax 访问之后触发。

(c) 支持在resultStream2 的 ajax 访问之后启动。

我知道 Bacon.js 的流或属性对自身有副作用,因此我的代码无法正常运行。 在 (b) 中,resultStream 的事件从 resultStream 对象中移除,导致 (*) 中的流为空。

resultStream 更改为函数(如triggerStream)接缝的方法效果很好,但在(b) 和(c) 时会导致resultStream 的两次独立的ajax 访问。

有什么想法可以实现我的方法吗?

【问题讨论】:

  • 问题在于您使用 Bacon.fromArray 作为源。 Bacon.fromArray 返回一个行为有点古怪的流,因为它将其内容吐出给第一个订阅者。您可以尝试使用更现实的来源(例如 Bacon.sequentially)来完成这项工作。
  • 关于 Bacon.fromArray 的事实对我来说是新的。非常感谢!但它似乎还没有工作...... onValue() at (b) 吃掉了所有流并且 (c) 不起作用。
  • 对不起,我被误解了。你的工作。太棒了!
  • @raimohanska 你应该发表你的评论作为答案,这样这个问题就会被标记为已回答。

标签: ajax coffeescript purely-functional bacon.js


【解决方案1】:

问题在于您使用Bacon.fromArray 作为源。此方法返回一个同步响应的流,该流实际上将其内容吐出给第一个订阅者。

您可以尝试更真实的来源,例如 Bacon.sequentially 来完成这项工作。或者您可以通过stream.delay(0) 将其更改为异步响应。

另请参阅 Bacon.js 常见问题解答:https://github.com/baconjs/bacon.js/wiki/FAQ#why-isnt-my-subscriber-called

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多