将Bacon.Bus值与promise的值相结合

时间:2014-05-14 21:57:45

标签: javascript promise frp bacon.js

我在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

1 个答案:

答案 0 :(得分:0)

看起来你正在寻找flatMap(再次):

busValuesWithPromise = bus.flatMap (busValue) ->
    Bacon.combineAsArray(promised, busValue)
busValuesWithPromise.onValues (fromPromise, fromBus) ->
    # every bus update, together with the promise value