我在BaconJS的FRP土地上迈出了一小步。我有以下代码:
# This will eventually get resolved with some value
dfd = Promise.defer()
promised = Bacon.fromPromise dfd.promise
# Values are occasionally being pushed in here
bus = new Bacon.Bus
# 1. attempt
bus.combine promised, (fromBus, fromPromise) ->
# This is never invoked
# 2. attempt
Bacon.combineAsArray( bus, promised ).onValues (fromBus, fromPromise) ->
# This is invoked only once for the latest value from the bus
# 3. attempt
promised.sampledBy(bus).onValue (fromPromise, fromBus) ->
# No invoke here at all
# These are called asynchronously during application lifespan
bus.push obj1
dfd.resolve value
bus.push obj2
bus.push obj3
我希望通过Bus更新每个交付的对象,其中包含promise对象的值,包括那些在promise被解析之前被推送到那里的对象。我可以这样做:
bus.onValue (fromBus) ->
promise.then (fromPromise) ->
...
是的,这有效,但我不喜欢它,我想看看FRP是否可以更优雅地解决它。你有什么提示吗?请问纯粹的玻璃钢怎么样?
我正在考虑其他一些方法。以下是实际发生的一些背景......
# Simple function that creates some object instance (if it haven't been created yet ) and returns it
getObject = (name) ->
unless obj = list[name]
obj = new Obj()
bus.push obj
对于添加到缓存中的每个对象,我需要将一些属性设置为来自Promise的值。基本上我可以这样做:
obj = new Obj()
dfd.promise.then (resolvedValue) ->
obj.someProperty = resolvedValue
这是没有FRP的完全可行的解决方案,但是您可能知道,每个.then
调用都被强制为异步。它以低廉的性能付出了代价。我想克服这一点。如果我理解正确,使用FRP只会调用.then
一次,然后提供静态值。问题仍然是如何做到的......
结帐fiddle。简而言之,它看起来像这样:
bus.flatMap(
Bacon.combineAsArray.bind Bacon, promised
).onValue ([fromPromise, fromBus]) ->
fromBus.specialProperty = fromPromise
答案 0 :(得分:0)
看起来你正在寻找flatMap
(再次):
busValuesWithPromise = bus.flatMap (busValue) ->
Bacon.combineAsArray(promised, busValue)
busValuesWithPromise.onValues (fromPromise, fromBus) ->
# every bus update, together with the promise value