RxJava- 在静态文本中放置几个 Observable 值?
RxJava- Placing several Observable values in a static body of text?
我听几个响应式编程的人说 "don't break the monad, just continue it"。我看到了这其中的优点。我仍然对某些情况感到困惑,尤其是当 Observable
最终被消费或订阅时。当必须同时消耗多个 observable 时,这会更加混乱,并且将它们组合成单个 observable 感觉不太实用。
比方说我有一个 TrackedAircraft
类型。它的一些属性是最终的,而其他属性是 Observable
.
public interface TrackedAircraft {
public int getFlightNumber();
public int getCapacity();
public Observable<String> getOrigin();
public Observable<String> getDestination();
public Observable<Integer> getMileage();
public Observable<Point> getLocation();
}
我可以很容易地将其连接到 GUI,只需订阅控件,以便在每个 属性 的每次发射时进行更新。但是电子邮件或静态文本正文呢?这不是那么简单,因为我能想到的不破坏 monad 的唯一方法是组合所有 observable,这听起来很痛苦,尤其是当我有一个 Observable 发射 TrackedFlights 时。
这种情况可以屏蔽吗?还是有一种我没有想到的更单一的方式来完成这个?
public static String generateEmailReportForFlight(TrackedAircraft flight) {
return new StringBuilder().append("FLIGHT NUMBER: ").append(flight.getFlightNumber()).append("\r\n")
.append("CAPACITY: ").append(flight.getCapacity()).append("\r\n")
.append("ORIGIN: ").append(flight.getOrigin() /*What do I do here without blocking?*/)
.append("DESTINATION: ").append(flight.getDestination() /*What do I do here without blocking?*/)
.append("MILEAGE: ").append(flight.getMileage() /*What do I do here without blocking?*/)
.append("LOCATION: ").append(flight.getLocation() /*What do I do here without blocking?*/)
.toString();
}
///
Observable<TrackedAircraft> trackedFlights = ...;
trackedFlights.map(f -> generateEmailReportForFlight(f));
可以使用flatMap + combineLatest:
Observable<TrackedAircraft> trackedFlights = ...
trackedFlights
.flatMap(flight -> emailReport(flight))
.subscribe(msg -> sendEmail(msg));
Observable<String> emailReport(TrackedAircraft flight) {
return Observable.combineLatest(
flight.getOrigin(),
flight.getDestination(),
flight.getMileage(),
flight.getLocation()
(origin, destination, mileage, location) -> {
return new StringBuilder()
.append("FLIGHT NUMBER: ").append(flight.getFlightNumber())
.append("\r\n")
.append("CAPACITY: ").append(flight.getCapacity())
.append("\r\n")
.append("ORIGIN: ").append(origin)
.append("\r\n")
.append("DESTINATION: ").append(destination)
.append("\r\n")
.append("MILEAGE: ").append(mileage)
.append("\r\n")
.append("LOCATION: ").append(location)
.toString();
}
)
}
我听几个响应式编程的人说 "don't break the monad, just continue it"。我看到了这其中的优点。我仍然对某些情况感到困惑,尤其是当 Observable
最终被消费或订阅时。当必须同时消耗多个 observable 时,这会更加混乱,并且将它们组合成单个 observable 感觉不太实用。
比方说我有一个 TrackedAircraft
类型。它的一些属性是最终的,而其他属性是 Observable
.
public interface TrackedAircraft {
public int getFlightNumber();
public int getCapacity();
public Observable<String> getOrigin();
public Observable<String> getDestination();
public Observable<Integer> getMileage();
public Observable<Point> getLocation();
}
我可以很容易地将其连接到 GUI,只需订阅控件,以便在每个 属性 的每次发射时进行更新。但是电子邮件或静态文本正文呢?这不是那么简单,因为我能想到的不破坏 monad 的唯一方法是组合所有 observable,这听起来很痛苦,尤其是当我有一个 Observable 发射 TrackedFlights 时。
这种情况可以屏蔽吗?还是有一种我没有想到的更单一的方式来完成这个?
public static String generateEmailReportForFlight(TrackedAircraft flight) {
return new StringBuilder().append("FLIGHT NUMBER: ").append(flight.getFlightNumber()).append("\r\n")
.append("CAPACITY: ").append(flight.getCapacity()).append("\r\n")
.append("ORIGIN: ").append(flight.getOrigin() /*What do I do here without blocking?*/)
.append("DESTINATION: ").append(flight.getDestination() /*What do I do here without blocking?*/)
.append("MILEAGE: ").append(flight.getMileage() /*What do I do here without blocking?*/)
.append("LOCATION: ").append(flight.getLocation() /*What do I do here without blocking?*/)
.toString();
}
///
Observable<TrackedAircraft> trackedFlights = ...;
trackedFlights.map(f -> generateEmailReportForFlight(f));
可以使用flatMap + combineLatest:
Observable<TrackedAircraft> trackedFlights = ...
trackedFlights
.flatMap(flight -> emailReport(flight))
.subscribe(msg -> sendEmail(msg));
Observable<String> emailReport(TrackedAircraft flight) {
return Observable.combineLatest(
flight.getOrigin(),
flight.getDestination(),
flight.getMileage(),
flight.getLocation()
(origin, destination, mileage, location) -> {
return new StringBuilder()
.append("FLIGHT NUMBER: ").append(flight.getFlightNumber())
.append("\r\n")
.append("CAPACITY: ").append(flight.getCapacity())
.append("\r\n")
.append("ORIGIN: ").append(origin)
.append("\r\n")
.append("DESTINATION: ").append(destination)
.append("\r\n")
.append("MILEAGE: ").append(mileage)
.append("\r\n")
.append("LOCATION: ").append(location)
.toString();
}
)
}