Справиться с побочными эффектами Bacon.js

Я новичок в Bacon.js, обычно пишу программы на Хаскеле. По своему опыту работы с Haskell я хочу описать некоторые ситуации в Bacon.js как чисто функционально-подобный подход.

Вот пример ситуации.

  • triggerStream это исходный поток.
  • resultStream пытается AJAX доступ, когда triggerStreamсобытия происходят.
  • resultStream2 также пытается AJAX-доступ после завершения resultStreamАякс доступ.

Это мой подход:

### =======
# 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)

(а) допускается к выполнению после каждого триггерного события, другими словами, оно выполняется до resultStreamАякс доступ.

(б) считается уволенным после resultStreamАякс доступ.

(c) предполагается начать после resultStream2Аякс доступ.

Я знаю, что потоки или свойства Bacon.js имеют побочные эффекты сами по себе, и поэтому мой код не может работать хорошо. В (б), resultStreamсобытия удалены из resultStream объект, который вызывает пустой поток в (*).

Подход, который меняет resultStream к функции (например, triggerStream) швы работают хорошо, но это вызывает независимость в два раза resultStreamДоступ Ajax, когда (б) и (в).

Есть ли идея реализовать мой подход?

1 ответ

Решение

Проблема в том, что вы используете Bacon.fromArray как источник Этот метод возвращает синхронно отвечающий поток, который практически выплевывает его содержимое первому подписчику.

Вы можете попробовать более реалистичный источник, такой как Bacon.sequentially чтобы сделать эту работу. Или вы можете сделать stream.delay(0) изменить его на асинхронно отвечающий.

См. Также FAQ по Bacon.js: https://github.com/baconjs/bacon.js/wiki/FAQ

Другие вопросы по тегам