在rx中创建资源的副作用(反应式扩展)

时间:2014-02-07 01:05:42

标签: javascript reactive-extensions-js rxjs

rx指南说尽可能避免副作用,如果不可避免的话,将它们放在do()(js中的doAction)子句中。

然而,UI中非常常见的副作用是创建一些在下游引用的资源(例如< div>)(通过子窗口小部件)。您必须捕获这些资源的句柄,以便可以传递它们。例如。如果你有一个数组,每个都需要一个div,你可以为每个创建一个div,并将这些div的句柄传递给子节点。

但是doAction()会丢弃副作用的返回值,因此您无法捕获创建的对象的句柄。你必须在select()中做副作用。

我看这一切都错了吗?创建的资源是状态,并且是副作用。你想要流中的状态,但你不能把它放在流中而不将副作用放在select()中,这是禁忌的。

2 个答案:

答案 0 :(得分:4)

请记住,它们只是指导方针。如果你想要一个副作用选择功能,你就会明白它将如何使用,那就去吧。

但是......你是否考虑过创建分离元素并仅将它们附加到订阅回调中的文档中?换句话说,不是资源的创造是副作用。只有当您对资源执行某些操作时。我已经使用过这种模式了几次......

$(someElement).onAsObservable("click")
    .select(function(ev) {
            return $("<div>");
     })
     ...do stuff to detached div
     .subscribe(function($el) {
          // finally attach it
          $(container).append($el);
     });

答案 1 :(得分:2)

这是FRP的常见问题。我没有找到比弯曲规则更好的方法。但是,我倾向于使用select / map,而不是使用selectMany / flatMap,这允许我直接返回事件流。

如下所示。 (该片段是Bacon.js代码,但可以很容易地转换为RxJs)

var allClicks = event.flatMap(function(value) {
  var widget = $("<input>") // etc
  $("form").append(widget)
  return widget.asEventStream("click")
})

因此,对于每个输入事件,您将创建一个新的UI并返回该事件流。结果流“allClicks”从生成的流中获取所有事件。