如何构建用于计数的递归流

how to build a recursive stream for counting numbers

我想构建自定义流,递归计算页数:

var pageStream = function(page, limit) {

  return Bacon.fromBinder(function(sink) {p
    if (page >= limit) {
      sink(new Bacon.End());
    } else {
      sink(Bacon.fromArray([page]));
      sink(new Bacon.Next(function() {
        return pageStream(page + 1, limit);
      }));
    }
  }).flatMapConcat(function(v) { return v; });
};


stream = pageStream(1, 5);

// If I use this code nothing is logged, why?
// stream.onEnd(function(v) {
//   console.log('done');
// });

stream.log();

我希望 pageStream 数到 limit 并结束直播。它可以计数到限制,但它不会发送最终的 end 事件。

此外,如果我收听 stream.onEnd,流根本不起作用。

这个任务不需要递归,但是如果你只是想要一些递归的例子,你可以这样做:

var pageStream = function(page, limit) {
  if (page > limit) {
    return Bacon.never();
  } else {
    return Bacon.once(page).concat(pageStream(page + 1, limit));
  }
}

但是我还是不推荐这个解决方案,例如 pageStream(1, 5) 它会生成:

Bacon.once(1).concat(
  Bacon.once(2).concat(
    Bacon.once(3).concat(
      Bacon.once(4).concat(
        Bacon.once(5).concat(
          Bacon.never())))));

这在大数字上表现不佳。

相反,我会这样做:

var pageStream = function(page, limit) {
  var arr = [];
  while (page <= limit) {
    arr.push(page);
    page++;
  }
  return Bacon.fromArray(arr);
}

Also if I listen to stream.onEnd, the stream doesn't work at all.

这是典型的 Bacon 陷阱,同步流如 .fromArray.oncehttps://github.com/baconjs/bacon.js/wiki/FAQ#why-isnt-my-subscriber-called

为避免这种情况,您可以使用 .sequentially() 代替 .fromArray(),并使用 .later() 代替 .once()

var pageStream = function(page, limit) {
  var arr = [];
  while (page <= limit) {
    arr.push(page);
    page++;
  }
  return Bacon.sequentially(0, arr);
}

var pageStream = function(page, limit) {
  if (page > limit) {
    return Bacon.never();
  } else {
    return Bacon.later(0, page).concat(pageStream(page + 1, limit));
  }
}