Игнорировать прошлые значения из потока событий FRP

Я использую BaconJS для создания двух таких потоков событий:

# Wait for start of the module
sStart = Bacon.fromCallback module.onStart.bind(module)
# Watch game ticks
sTick = Bacon.fromEventTarget emitter, 'tick'
# Combine it to do something
Bacon.onValues sStart, sTick, ->
    # Do something on each tick, but only when module has been started

Я хочу использовать его для синхронизации. Как только модуль запущен, он должен начать прослушивание тиков, не раньше. Это почти работает, но обратный вызов вызывается для всех прошлых тиков, которые были отправлены до запуска модуля, а не только для последнего. Чем я хочу, чтобы этот обратный вызов вызывался для каждого следующего тика.

Я в значительной степени начинаю с FRP, возможно, есть какой-то элегантный способ справиться с этим, но я просто не вижу его сейчас. Любые идеи ?


person FredyC    schedule 14.05.2014    source источник


Ответы (2)


Похоже, вы злоупотребляете Bacon.onValues, целью которого является создание нового потока.

Если вы хотите дождаться запуска модуля, просто зарегистрируйте слушателя только тогда, когда он запустится:

sTick = Bacon.fromEventTarget emitter, 'tick'

module.onStart ->
  # when module has been started
  sTick.onValue ->
    # Do something on each tick

Для полного стиля FRP вы должны использовать flatMap:

sStart = Bacon.fromCallback module.onStart.bind(module)
# Watch game ticks
sTick = Bacon.fromEventTarget emitter, 'tick'
# Combine it to a new stream that is made from sTicks by each sStart event
sTicksAfterStart = sStart.flatMap -> sTick
sTickeafterStart.onValue ->
  # Do something on each tick
person Bergi    schedule 14.05.2014
comment
Согласен, за исключением предполагаемой цели метода onValue, который не создает новый поток. Он также не использовался в исходном вопросе. - person raimohanska; 14.05.2014
comment
Да, первое решение в значительной степени очевидно, но поскольку я использую это начальное событие для синхронизации с некоторыми другими событиями, я подумал, что может быть лучше использовать поток и для этого, и я хотел избавиться от обреченности обратного вызова. Ваше решение с flatMap прекрасно работает. Спасибо. - person FredyC; 14.05.2014
comment
@raimohanska Я даже не использовал onValue, а onValues, что должно быть сокращением, чтобы работать как Bacon.combineAsArray(...).onValues(). - person FredyC; 14.05.2014
comment
@raimohanska: А, спасибо, опечатка. Нет даже Bacon.onValue - person Bergi; 14.05.2014
comment
@FredyC: Вы также можете использовать flatMapLatest или более похожий на обещание flatMapFirst, они должны работать одинаково для одного события start. - person Bergi; 14.05.2014

Вы можете пропустить значения, используя skipUntil, как здесь.

startE = Bacon.fromCallback module.onStart.bind(module)
tickE = Bacon.fromEventTarget emitter, 'tick'
tickE.skipUntil(startE).onValue (tickValue) -> console.log tickValue

Приведенное выше решение flatMap тоже верно, но мне кажется, что skipUntil легче читать.

person raimohanska    schedule 14.05.2014
comment
Это тоже выглядит великолепно и, возможно, более читабельно, чем flatMap. Кажется, мне следовало подождать дольше с пометкой ответа. Мне это нравится больше. - person FredyC; 14.05.2014