我不确定我对此有多正确,所以如果有任何专家能够纠正我这一点,也将不胜感激。我目前的理解是,可观察者是懒惰的,并且在订阅之前不会产生价值。如果发生错误,则observable不再发送任何值。在很多情况下,这不是想要的。
在下面的代码示例中,我得到了珀斯和伦敦的天气,如果发生错误,则返回一个指示错误发生的对象。这几乎意味着订阅者的错误阻止不会被调用,但成功将会成功,我将不得不看看它是否失败并改变了逻辑。这是最好的方法吗????
拉链操作员也会等待所有的obs产生一个值而不管订购和返回什么时候产生一个单独的值?
代码如下:
window.application = application || {};
window.application.stocks = (function(){
function getWeather(city, country){
return $.ajaxAsObservable({
url: 'http://api.openweathermap.org/data/2.5/weather?q=' + city + ',' + country,
dataType: 'jsonp'
}).map(function(v){
return {
city : city,
country : country,
temperature : v.data.main.temp
};
});
}
var requests = Rx.Observable
.interval(500)
.timestamp()
.map(function(v){
var perth = getWeather('perth','au');
var london = getWeather('london','uk');
return Rx.Observable.zip(perth,london, function(a,b){
return {
a : a,
b : b,
timestamp : v.timestamp,
failure : false,
};
}).retry(3)
.catch(Rx.Observable.return({ failure: true }));
})
.concatAll();
var selector = $('#weather');
var subscriber = requests.forEach(
function(data){
if(data.failure){
$('<li>Failure in receiving the temperature</li>').appendTo(selector);
return;
}
$('<li> at: ' + data.timestamp + ' for: ' + data.a.city + ' - ' + data.a.temperature + '</li>').appendTo(selector);
$('<li> at: ' + data.timestamp + ' for: ' + data.b.city + ' - ' + data.b.temperature + '</li>').appendTo(selector);
},
function(error){
selector.text('');
$('<li>Error: ' + error + '</li>').appendTo('#weather');
},
function(){
}
);
});
非常感谢任何建议和提示。
提前致谢。
布莱尔。
答案 0 :(得分:3)
您可能应该将.forEach()
替换为.subscribe()
,因为其中一个是另一个的别名,.subscribe()
在这种情况下更常见且更明确。
subscribe()可以接受三个函数作为参数onNext
(第一个函数),onError
(第二个函数,可选),onComplete
(第三个函数,可选)。因此,您可能只需在subscribe()中提供第二个函数来处理错误,从而达到您想要的效果。然后,您不需要.catch()
运算符来插入类似标志的事件。
此外,对于您的特定用例,perth
和london
Observable在概念上是独立的(它们彼此之间没有依赖关系),您希望使用.combineLatest()
而不是{{ 1}}。有关两者之间差异的详细信息,请参阅this answer。
答案 1 :(得分:0)
有趣的是,这篇文章说你需要标记错误,以便蒸汽不能完成。
Idiomatic way to recover from stream onError
根据我目前对RX的理解和测试,如果在进程中抛出错误,将调用订阅的onError处理程序,但它将完成流。
意味着订户不会再收到任何消息。