Другой пример:
class func getExchangeRate(#baseCurrency: String, foreignCurrency:String, completion: ((result:Double?) -> Void)!){
let baseURL = kAPIEndPoint
let query = String(baseCurrency)+"_"+String(foreignCurrency)
var finalExchangeRate = 0.0
if let url = NSURL(string: baseURL + query) {
NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in
if ((data) != nil) {
let jsonDictionary:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as NSDictionary
if let results = jsonDictionary["results"] as? NSDictionary{
if let queryResults = results[query] as? NSDictionary{
if let exchangeRate = queryResults["val"] as? Double{
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
dispatch_async(dispatch_get_main_queue()) {
completion(result: exchangeRate)
}
}
}
}
}
}
else {
completion(result: nil)
}
}.resume()
}
}
Вызов:
Currency.getExchangeRate(baseCurrency: "USD", foreignCurrency: "EUR") { (result) -> Void in
if let exchangeValue = result {
print(exchangeValue)
}
}
Flux.repeat
и Mono.repeat
будут повторно подписываться на источник, поэтому каждый предыдущий шаг источника будет повторяться с новой подпиской.
Поскольку calculateNextResult
и compareResults
являются синхронными операциями в вашем примере, вы можете использовать простой цикл for
для повторения ...
public Flux<Boolean> run(some params, Flux<Integer> prevResults){
return prevResults.map(elem -> {
for (int i = 0; i < 5; i++) {
if (compareResults(elem, calculateNextResult(some params))) {
return true;
}
}
return false;
});
}
Если бы calculateNextResult
или compareResults
были реактивными методами, возвращающими Mono
, то вы могли бы использовать flatMap
вместо map
и использовать один из методов Mono.repeat*
.
Например, что-то вроде этого:
private Mono<Integer> calculateNextResult(some params) {
// some implementation
}
private Mono<Boolean> compareResults(int prevRes, int nextRes) {
// some implementation
}
public Flux<Boolean> run(some params, Flux<Integer> prevResults){
return prevResults.flatMap(prevResult ->
calculateNextResult(some params)
.flatMap(nextResult -> compareResults(prevResult, nextResult))
.filter(comparisonResult -> comparisonResult)
.repeatWhenEmpty(Repeat.times(5))
.defaultIfEmpty(false));
}
В этом примере repeatWhenEmpty
вызовет новую подписку на Mono, созданную в flatMap, что приведет к пересчитать (при условии, что Mono, возвращенный из calculateNextResult
, настроен для расчета значения для каждой подписки).