Hwangho Kim
Hwangho Kim

Reputation: 649

RxSwift & alamofire, How to send http request after previous request arrived?

I need to send http request in RxSwift & Alamofire circumstance and send it synchronously which means ...

send(1)...response(1)

-------------------- send(2)...response(2)

-----------------------------------------send(3)...response (3)

and This is my code

            Observable.from(devicesArray)
            .concatMap { (device) in
                return HTTPRequest.deleteDevice(withDevice: device)
            }.subscribe({ (event) in
                log.debug("Remove device successfully")
            }).disposed(by: self.disposeBag)

and deleteDevice is

func deleteDevice(withDevice device:Device) -> Single<String> {

    return Alamofire.request("http://example.com/\(device.deviceId)", method: .delete, parameters: nil, headers: self.headers()).rx
        .responseJSON()
        .retry(self.retryMaxAttempCount)
        .asSingle()
        .observeOn(SerialDispatchQueueScheduler(qos: .default))
        .map({ (response) in
            guard let json = response.value as? [String: Any] else {
                throw HTTPManagerError.invalidResponse
            }

            guard let resultCode = json["resultCode"] as? String else {
                throw HTTPManagerError.invalidResponse
            }

            if resultCode == "0000" || resultCode == "0101" {
                return resultCode
            } else {
                throw HTTPManagerError.invalidResponse
            }
        })
        .observeOn(MainScheduler.instance)
}

Now every single HTTPRequest.deleteDevice function requested in parallel.

So How could I make this request wait until a previous request get finished?

Thanks.

Upvotes: 2

Views: 991

Answers (1)

Daniel T.
Daniel T.

Reputation: 33979

The key here is to make an array of observables and concat them:

// first we create a deleteDevice observable for each item. 
// Remember, they don't actually make a network call until subscribed to and concat only subscribes to each once the previous one is done.
Observable.concat(
    devicesArray.map { deleteDevice(withDevice: $0) }
        .map { $0.asObservable() } // because concat doesn't exist for Singles.
        .map { $0.catchErrorJustReturn("\($0) not deleted.") } // make sure that all deletes will be attempted even if one errors out.
    )
    // the above will emit a string every time a delete finishes.
    // `.toArray()` will gather them together into an array.
    .toArray()
    .subscribe(onNext: { results in

    })
    .disposed(by: disposeBag)

Upvotes: 1

Related Questions