2016-04-18 2 views
1

У меня есть несколько запросов:Как синхронизировать несколько Alamofire запросы

var data1: MyData? 
var data2: MyData? 
var data3: MyData? 

func makeRequest(url: String, completion: (result: ResponseResult, data: MyData?) -> Void){ 
    Alamofire.request(.GET, url).responseJSON { response in 
     switch response.result { 
     case .Success(let JSON): 
     completion(result: .Success, MyData(JSON)) 
     case. Failure(let error): 
     completion(result: .Failure, nil) 
     } 
    } 
} 

makeRequest(url1){ result, data in 
    data1 = data 
} 
makeRequest(url2){ result, data in 
    data2 = data 
} 
makeRequest(url3){ result, data in 
    data3 = data 
} 

И после того, как было получено все данные я должен вызвать следующую функцию:

workWithData(data1, data2: data2, data3: data3) 

Как сделать барьер для этого три запроса в эта ситуация?

+0

после успешного вызова третьего запроса позвоните в вашу функцию. –

+0

@AshishKakkad Запросы Alamofire являются асинхронными –

+0

Вы используете реактивный какао или что-то подобное? Если это так, вы можете перевести вызов в сигнал, а затем вызывать его последовательно (или все, что хотите). – KlimczakM

ответ

6

Вы должны использовать DispatchGroup, и не забывайте о тупиках.

var data1: MyData? 
var data2: MyData? 
var data3: MyData? 

func makeRequest(url: String, completion: (result: ResponseResult, data: MyData?) -> Void){ 
    Alamofire.request(.GET, url).responseJSON { response in 
     switch response.result { 
     case .Success(let JSON): 
      completion(result: .Success, MyData(JSON)) 
     case. Failure(let error): 
      completion(result: .Failure, nil) 
     } 
    } 
} 

let downloadGroup = DispatchGroup() 

downloadGroup.enter() 
downloadGroup.enter() 
downloadGroup.enter() 

makeRequest(url1){ result, data in 
    data1 = data 
    downloadGroup.leave() 
} 
makeRequest(url2){ result, data in 
    data2 = data 
    downloadGroup.leave() 
} 
makeRequest(url3){ result, data in 
    data3 = data 
    downloadGroup.leave() 
} 

DispatchQueue.global(qos: .background).async { 
    downloadGroup.wait() 
    DispatchQueue.main.async { 
     workWithData(data1, data2: data2, data3: data3) 
    } 
} 
1

Семафор должен работать на вас. Рассмотрим следующее:

var data1: NSData? 
var data2: NSData? 
var data3: NSData? 

func makeRequest(url: String, completion: (data: NSData?) -> Void){ 

    let request = Alamofire.request(.GET, "https://google.com").responseJSON(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { closureResponse in 

     completion(data: NSData()) 
    } 
} 

let sem = dispatch_semaphore_create(0) 

makeRequest("1"){ data in 
    data1 = data 
    dispatch_semaphore_signal(sem) 
} 
makeRequest("2"){ data in 
    data2 = data 
    dispatch_semaphore_signal(sem) 
} 
makeRequest("2"){ data in 
    data3 = data 
    dispatch_semaphore_signal(sem) 
} 

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) 
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) 
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) 

print("123") 

Комментарий на комментарий @James, я провел некоторое время, играя с Alamofire. То, что я выяснил, по умолчанию предоставляет обратные вызовы в основной очереди. Это не хорошо с моей точки зрения, я предпочитаю минимизировать нагрузку на основной поток. Я бы рекомендовал использовать параллельную очередь для доставки обратного вызова.

0

Я думаю, вы должны проверить, стоит ли продолжать в конце Alamofire.request:

func makeRequest(url: String, completion: (result: ResponseResult, data: MyData?) -> Void){ 
    Alamofire.request(.GET, url).responseJSON { response in 
     switch response.result { 
     case .Success(let JSON): 
      completion(result: .Success, MyData(JSON)) 
     case. Failure(let error): 
      completion(result: .Failure, nil) 
     } 

     if data1 != nil && data2 != nil && data3 != nil { 
      workWithData(data1, data2: data2, data3: data3) 
     } 
    } 
} 
+0

Если Alamofire использует параллельную очередь под капотом для доставки обратных вызовов, это может быть потенциальным источником состояния гонки. Я бы рекомендовал это выяснить, и если мое предположение верно, то *, если check * следует поместить под примитив синхронизации (lock, dispatch_sync или что-то еще, что вы хотите). –

+0

Не могли бы вы рассказать об этом? Что такое гонка? Какой бы последний 'data123' был установлен, введите' if', а остальные - нет. Звонки на 'завершение' внутри' .responseJSON' не являются асинхронными, поэтому они будут завершены до выключения коммутатора. – BallpointBen

Смежные вопросы