首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >流与其他流的Bacon.js控制缓冲

流与其他流的Bacon.js控制缓冲
EN

Stack Overflow用户
提问于 2014-07-11 06:29:18
回答 3查看 494关注 0票数 3

我想在Bacon.js中缓冲Bacon.js中的buffer(closingSelector)值,就像buffer(closingSelector)在RxJava中的行为一样。当“控制器流”(closingSelector in RxJava方法)发出一个新值时,事件缓冲区就会被刷新。

因此,我希望流输出类似于stream.bufferWithTimeOrCount中的输出,但是我不想用时间间隔或事件计数来控制缓冲,而是想用其他流来控制缓冲。

是否有一种在Bacon.js中实现这一功能的简单方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-16 07:04:53

Bacon.js没有所需的函数,所以我查看了bacon.js源并编写了holdWhen的修改版本。

代码语言:javascript
运行
复制
Bacon.EventStream.prototype.bufferUntilValue = function(valve) {
var valve_ = valve.startWith(false);

  return this.filter(false).merge(valve_.flatMapConcat((function(_this) {
    return function() {
        return _this.scan([], (function(xs, x) {
            return xs.concat(x);
        }), {
            eager: true
        }).sampledBy(valve).take(1);
    };
  })(this)));
};

要查看此操作,请查看此jsFiddle

票数 1
EN

Stack Overflow用户

发布于 2014-07-14 07:46:33

自0.7.14以来可用的Bacon.holdWhen几乎可以满足您的需要,不过缓冲事件是一个接一个地发出的:

如果阀门中的最后一个事件是真实的,stream.holdWhen(阀门)会暂停并缓冲事件流。当阀门失效时,所有缓冲事件都会被释放。

如果需要将缓冲事件作为单个事件发出,则可以尝试如下所示:

代码语言:javascript
运行
复制
// source streams
var sourceObservable = Bacon.interval(1000);
var closingSelector = new Bacon.Bus();

// Constructing a new Observable where we're going to keep our state.
// 
// We need to keep track of two things: 
//   - the buffer that is currently being filled, and
//   -  a previous buffer that is being flushed.
// The state will then look like this:
//   [ buffer, flushed]
// where both buffer and flushed is an array of events from the source observable.

// empty initial state
var initialState = {buffer: [], flushed: []}

// There are two operations on the state: appending a new element to the buffer 
// and flushing the current buffer:

// append each event from the source observable to the buffer,
// keeping flushed unchanged
var appends = sourceObservable.map(function(e) {
   return function(state) {
       state.buffer.push(e); return state; 
   } 
});

// each event from the closingSelector replaces the `flushed` with 
// the `buffer`'s contents, inserting an empty buffer.
var flushes = closingSelector.map(function(_) {
   return function(state) { return {buffer: [], flushed: state.buffer} }
})

// merge appends and flushes into a single stream and apply them to the initial state
var ops = appends.merge(flushes)
var state = ops.scan(initialState, function(acc, f) { return f(acc) });

// resulting stream of flushed events
var flushed = state.sampledBy(closingSelector).map(function(state) { return state.flushed })

// triggered with `closingSelector.push({})`
flushed.onValue(function(x) { console.log("flushed", x) })
票数 1
EN

Stack Overflow用户

发布于 2014-07-15 22:25:55

stream.holdWhen(valve)看起来就像你想要的那样。它的工作方式与buffer(closingSelector)略有不同:它不是一直在缓冲,而是在closingSelector事件上刷新缓冲区,而是切换缓冲区取决于value流中的最后一个值。

也许您可以使用holdWhen,但是如果您想要像buffer(closingSelector)中那样的行为,您可以这样做:

代码语言:javascript
运行
复制
var result = sourceStream.holdWhen(closingSelector.flatMap(function(){
  return Bacon.fromArray([false, true]);
}).toProperty(true));

对于来自closingSelector的每个事件,我们在value流中生成两个具有truefalse值的事件,即关闭缓冲(这会触发刷新),然后立即打开它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24691378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档