我是Bacon.js的新手,通常在Haskell中编写程序。 根据我对Haskell的经验,我想将Bacon.js中的一些情况描述为纯粹的功能性方法。
以下是一个示例情况。
triggerStream
是源流。resultStream
在triggerStream
事件发生时尝试访问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)和(b)和{b}时,它会导致resultStream
ajax访问独立两次(c)中。
有没有想法实现我的方法?
答案 0 :(得分:4)
问题在于您使用Bacon.fromArray
作为来源。此方法返回一个同步响应的流,实际上将其内容吐出到第一个订阅者。
您可以尝试更实际的来源,例如Bacon.sequentially
来完成这项工作。或者您可以stream.delay(0)
将其更改为异步响应。
另见Bacon.js常见问题解答:https://github.com/baconjs/bacon.js/wiki/FAQ#why-isnt-my-subscriber-called