我是RxJS的新手,想知道是否有人可以帮助我。
我想从请求流(有效负载数据)创建一个同步的响应流(最好带有相应的请求)。
我基本上希望逐个发送请求,每个请求等待最后一个请求。
我尝试了这个,但它会立即发送所有内容(jsbin):
var requestStream, responseStream;
requestStream = Rx.Observable.from(['a','b','c','d','e']);
responseStream = requestStream.flatMap(
sendRequest,
(val, response)=>{ return {val, response}; }
);
responseStream.subscribe(
item=>{
console.log(item);
},
err => {
console.err(err);
},
()=>{
console.log('Done');
}
);
function sendRequest(val) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{resolve('result for '+val);},1000);
});
};

以下工作在某种程度上,但不会对请求数据使用流(jsbin)。
var data, responseStream;
data = ['a','b','c','d','e'];
responseStream = Rx.Observable.create(observer=>{
var sendNext = function(){
var val = data.shift();
if (!val) {
observer.onCompleted();
return;
}
sendRequest(val).then(response=>{
observer.onNext({val, response});
sendNext();
});
};
sendNext();
});
responseStream.subscribe(
item=>{
console.log(item);
},
err => {
console.err(err);
},
()=>{
console.log('Done');
}
);
function sendRequest(val) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{resolve('response for '+val);},Math.random() * 2500 + 500);
});
};

谢谢!
修改
只是澄清一下,这就是我想要实现的目标:
"发送A,当您收到A的回复时,发送B,当您收到B的回复时,发送C等..."
使用concatMap和defer,正如user3743222所建议的那样,似乎是这样做的(jsbin):
responseStream = requestStream.concatMap(
(val)=>{
return Rx.Observable.defer(()=>{
return sendRequest(val);
});
},
(val, response)=>{ return {val, response}; }
);
答案 0 :(得分:3)
尝试在第一个代码示例中用flatMap
替换concatMap
,并告诉我结果行为是否与您要查找的内容相符。
responseStream = requestStream.concatMap(//I replaced `flatMap`
sendRequest,
(val, response)=>{ return {val, response}; }
);
基本上concatMap
具有与flatMap
类似的签名,行为的差异在于它会等待当前的observable在继续下一个之前被展平。所以这里:
requestStream
值将被推送到concatMap
运营商。concatMap
运算符将生成sendRequest
observable,并且该observable中的任何值(似乎是元组(val, response)
)都将通过选择器函数和对象结果传递其中将通过下游sendRequest
完成时,将处理另一个requestStream
值。或者,您可能希望使用defer
来推迟执行sendRequest
。
responseStream = requestStream.concatMap(//I replaced `flatMap`
function(x){return Rx.Observable.defer(function(){return sendRequest(x);})},
(val, response)=>{ return {val, response}; }
);