Заказать сетевые запросы результат с RxSwift - PullRequest
3 голосов
/ 22 марта 2019

В настоящее время у меня есть набор сетевых запросов на запуск. Проблема в том, что мне нужно упорядочить результаты, чтобы они соответствовали порядку, в котором я их запустил.

Мой текущий код следующий:

for url in config.fieldImages.map ({ URL(string: $0)! }) {
    self.getWheelFieldImage(url: url)
        .takeUntil(.inclusive, predicate: { (_) -> Bool in
            images.count == config.fieldImages.count - 1
        })
        .subscribe(onNext: { (anImage) in
            images.append(anImage)
        }, onError: { (error) in
            completion(nil, nil, error)
        }, onCompleted: {
            completion(images, false, nil)
            self.lastUpdate = Date()
        }, onDisposed: {
    })
    .disposed(by: self.disposeBag)
}

Мне интересно, есть ли простой способ упорядочить эти результаты в том же порядке, в котором я их запустил, используя RxSwift .

EDIT:

Я пытаюсь объяснить проблему лучше. У меня есть этот массив с N URL, и я запускаю запросы один за другим (1,2,3,4 ...).

Мне нужно вернуть результат этих запросов в том же порядке (R1, R2, R3, R4, где R1 - ответ на запрос 1 и т. Д ...), чтобы сохранить изображения в результирующем массиве.

Я могу подождать, пока все закончится. Нет проблем.

1 Ответ

2 голосов
/ 22 марта 2019

Без особых изменений в исходном коде вы можете достичь этого, используя enumerated() в своем списке URL-адресов как:

/// Prefill your images with nil for each image
var images = Array<Int?>(repeating: nil, count: config.fieldImages.count)
for (index, url) in config.fieldImages.map ({ URL(string: $0)! }).enumerated() {
    self.getWheelFieldImage(url: url)
        .takeUntil(.inclusive, predicate: { (_) -> Bool in
            images.count == config.fieldImages.count - 1
        })
        .subscribe(onNext: { (anImage) in
            images[index] = anImage /// Store on proper position
        }, onError: { (error) in
            completion(nil, nil, error)
        }, onCompleted: {
            completion(images, false, nil)
            self.lastUpdate = Date()
        }, onDisposed: {
    })
    .disposed(by: self.disposeBag)
}

Вероятно, большинство RxWay будет использовать оператор zip как:

let streams = config.fieldImages
    .map { URL(string: $0)! }
    .map { self.getWheelFieldImage(url: $0) }
let images = Observable.zip(streams) // Observable<[UIImage]>
    .subscribe(
        onNext: { [weak self] images in
            completion(images, false, nil)
            self?.lastUpdate = Date()
        }, 
        onError: { error in
            completion(nil, nil, error)
        }
    )
    .disposed(by: self.disposeBag)

Подробнее о zip можно прочитать в документации

...