我有一个数字流,我必须使用诺言将它们变成一个帖子流。我想懒洋洋地做这件事。因此,如果我从帖子流中.take(1)
,它只会将一个数字转换为帖子。
这是从数字中获取帖子的承诺:
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);
});
};
我只对第一篇文章感兴趣,因此take(1)
,它应该拨打getPost
一次。
如果我使用map
,则流工作为懒惰,请拨打getPost
一次。如果我使用flatmap
,则会为所有数字调用getPost
。
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();
但是map
会返回一个承诺,而flatMap
会返回该帖子。如何使用返回promise值的惰性流?
答案 0 :(得分:2)
flatMap
立即获取promises创建的所有流,并立即使用所有流生成新流。直播你已经观察到这不是懒惰,并会立即调用所有承诺返回功能。
您希望一次发生一次,因此您应该使用flatMapConcat
。它不是一次性地获取所有流,而是一次一个地调用它们,而不是一次调用它们 - 这是您通常期望.flatMap
在其他一些FRP库中执行的操作。请注意,如果您需要一次n
,请使用flatMapWithConcurrencyLimit
进行概括。
以下是针对类似案例使用flatMapConcat
的示例:
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();