【问题标题】:Combining Bacon.Bus values with value from promise将 Bacon.Bus 的价值与承诺的价值相结合
【发布时间】:2014-05-14 21:57:45
【问题描述】:

我正在使用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 是否可以更优雅地解决它。请问你有什么纯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

【问题讨论】:

  • 很高兴看到你取得进步!只是一个旁注 - 一个承诺是一次性的事情,只能解决一次,因此 Bacon.fromPromise 创建一个只获得一个值或错误的流。为什么在这里使用 deferred?
  • @BenjaminGruenbaum Deferred 只是为了举例,所以你可以看到我正在中间的某个地方解决它。我认为使用fromPromise 将观察承诺的解决,而不是保持价值并将其提供给任何消费者。这不是正确的吗?将其转换为.toProperty 会有所帮助吗?

标签: javascript promise frp bacon.js


【解决方案1】:

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

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

【讨论】:

  • 嗯,这看起来和我没有 FRP 的解决方案完全一样 :) 猜猜 FRP 没那么神奇。我宁愿看到一些闭包较少的解决方案,并且在一个函数调用中同时包含两个值,正如您在我的三次失败尝试中看到的那样。
  • 嗯,关键是它现在确实返回了一个流 - 我可能没有足够强调这一点。
  • 嗯,我明白了,但这只是糖。闭包仍然存在:(
  • 好吧,FRP 总是“只是糖” :-) 但是,为了消除封闭,我现在找到了我认为合适的功能:combineAsArray
  • 谢谢@Bergi!这肯定看起来更好一些,虽然我不太喜欢创建新流然后不得不使用onValues,但我想这只是我必须接受的 FRP 的一部分:) 我用工作做了小fiddle解决方案并稍微完善它。
猜你喜欢
  • 2017-12-22
  • 2021-07-11
  • 1970-01-01
相关资源
最近更新 更多