map a stream to lazy promise stream

笑着哭i 提交于 2019-12-10 10:35:29

问题


I have a I have a stream of numbers, I have to turn them into a stream of posts using a promise. And I want to do this lazily. So if I do .take(1) from the post stream, it will turn only one number to a post.

This is the promise that gets a post from a number:

var getPost = function(author) {
  console.log('get post' + author);
  return new RSVP.Promise(function(resolve, reject) {
    setTimeout(function() {
      var result = "Post by " + author;
      resolve(result);
    }, 1000);
  });
};

I am only interested in first post, thus take(1), and It should call getPost once.

If I use map, the stream works lazy, calls getPost once. If I use flatmap, it calls getPost for all the numbers.

var lazyStream = Bacon.fromArray([1, 2, 3, 4]).map(function(value) {
  return Bacon.fromPromise(getPost(value));
});

var nonLazyStream = Bacon.fromArray([1, 2, 3, 4]).flatMap(function(value) {
  return Bacon.fromPromise(getPost(value));
});

lazyStream.take(2).log();
//nonLazyStream.take(2).log();

However map returns a promise, while flatMap returns the post itself. How do I have a lazy stream that returns the value of promise?


回答1:


flatMap takes all the streams created by the promises at once and spawns a new stream using all of the streams at once. Live you have observed this is not lazy and will call all the promise returning functions at once.

You want that to happen one at a time so you should use flatMapConcat. Instead of taking all the streams at once it will call them one at a time invoking the promises one by one - this is what you'd normally expect .flatMap to do in some other FRP libraries. Note that this generalizes using flatMapWithConcurrencyLimit if you ever need it to do n at a time.

Here is an example using flatMapConcat for a similar case:

function delayPromise(val){ // delayed promise simulating an async request
    return new Promise(function(resolve){
      setTimeout(function(){ console.log("Resolve timeout"); resolve(val); }, 500);  
    });
}

var stream = Bacon.fromArray([1, 2, 3, 4]).flatMapConcat(function(value) {
  return Bacon.fromPromise(delayPromise(value));
});

stream.take(1).log();

Fiddle link



来源:https://stackoverflow.com/questions/27657538/map-a-stream-to-lazy-promise-stream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!