我试图理解响应式扩展(Rx)的正确使用场景。一些常见实例是处理UI事件(例如拖放和绘制),以及建议使用Rx处理异步应用程序/操作,比如Web服务调用。
我正在开发一个需要为REST服务编写小型客户端API的应用程序。我需要调用四个REST端点,其中三个用于获取一些参考数据(机场、航空公司和状态),第四个是主要服务,可以根据给定机场提供航班时间。
我创建了暴露三个参考数据服务的类,并且这些方法看起来像这样:
public Observable<IEnumerable<Airport>> GetAirports()
public Observable<IEnumerable<Airline>> GetAirlines()
public Observable<IEnumerable<Status>> GetStatuses()
public Observable<IEnumerable<Flights>> GetFlights(string airport)
在我的GetFlights方法中,我希望每个航班都持有一个出发机场和操作该航班的航空公司的引用。为此,我需要从GetAirports和GetAirlines获取数据。每个机场、航空公司和状态都将被添加到一个字典中,以便在解析每个航班时轻松地设置引用。
flight.Airport = _airports[flightNode.Attribute("airport").Value]
flight.Airline = _airlines[flightNode.Attribute("airline").Value]
flight.Status = _statuses[flightNode.Attribute("status").Value]
我的当前实现看起来像这样:
public IObservable<IEnumerable<Flight>> GetFlightsFrom(Airport fromAirport)
{
var airports = new AirportNamesService().GetAirports();
var airlines = new AirlineNamesService().GetAirlines();
var statuses = new StatusService().GetStautses();
var referenceData = airports
.ForkJoin(airlines, (allAirports, allAirlines) =>
{
Airports.AddRange(allAirports);
Airlines.AddRange(allAirlines);
return new Unit();
})
.ForkJoin(statuses, (nothing, allStatuses) =>
{
Statuses.AddRange(allStatuses);
return new Unit();
});
string url = string.Format(_serviceUrl, 1, 7, fromAirport.Code);
var flights = from data in referenceData
from flight in GetFlightsFrom(url)
select flight;
return flights;
}
private IObservable<IEnumerable<Flight>> GetFlightsFrom(string url)
{
return WebRequestFactory.GetData(new Uri(url), ParseFlightsXml);
}
当前的实现基于Sergey的回答,使用ForkJoin确保顺序执行,并且在Flights之前加载引用数据。这个实现比我以前的实现要更加优雅,不需要触发“ReferenceDataLoaded”事件。