问题
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