1

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

这是一个示例情况。

  • triggerStream是源流。
  • resultStreamtriggerStream当's 事件发生时尝试 ajax 访问。
  • resultStream2完成 ajax 访问后也会尝试 ajaxresultStream访问。

这是我的方法:

### =======
# 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) 支持在每个触发事件之后执行,换句话说,它在resultStreamajax 访问之前执行。

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

(c) 支持在resultStream2ajax 访问之后启动。

我知道 Bacon.js 的流或属性对自己有副作用,所以我的代码不能正常工作。在 (b) 中,resultStream的事件从resultStream对象中删除,这导致 (*) 中的流为空。

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

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

4

1 回答 1

4

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

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

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

于 2014-10-02T19:40:38.467 回答