Подождите, пока закончится несколько URLSessionDataTask? [Дубликат]

Я только что добавил этот код на мой частичный вид и решил проблему, хотя и не очень чистую, она работает. Вы должны убедиться, что идентификаторы объектов, которые вы просматриваете.

$ (document) .ready (function () {$ ("# Profile_ProfileID"). Selectmenu ({icons: {button: 'ui-icon -circle-arrow-s '}}); $ ("# TitleID_FK"). selectmenu ({icons: {button:' ui-icon-circle-arrow-s '}}); $ ("# CityID_FK"). selectmenu ({icons: {button: 'ui-icon-circle-arrow-s'}}); $ ("# GenderID_FK"). selectmenu ({icons: {button: 'ui-icon-circle-arrow-s' }}); $ ("# PackageID_FK"). Selectmenu ({icons: {button: 'ui-icon-circle-arrow-s'}});});
5
задан Eman H 16 September 2016 в 15:34
поделиться

2 ответа

Вы должны использовать группы отправки, вводя группу перед выдачей запроса и оставляя группу в обработчике завершения запроса. Итак, давайте предположим, что на секунду у вас был какой-то метод, который выполнял асинхронный запрос, но предоставил параметр обработчика завершения, который был бы закрыт, который будет вызываться при выполнении сетевого запроса:

func perform(request: URLRequest, completionHandler: @escaping () -> Void) { ... }

Чтобы запустить эти два одновременных запроса и получить уведомление, когда они будут выполнены, вы сделаете что-то вроде:

let group = DispatchGroup()

group.enter()
perform(request: first) {
    group.leave()
}

group.enter()
perform(request: second) {
    group.leave()
}

group.notify(queue: .main) {
    print("both done")
}

. Очевидно, что ваша реализация perform(request:) может значительно различаться (например, у вас может быть закрытие передает данные назад), но шаблон тот же, независимо от того, записываете ли вы свой собственный сетевой код с помощью URLSession или с помощью Alamofire. Просто используйте группы GCD, входящие в группу при создании запросов и оставляя группу в обработчике завершения асинхронного запроса.

15
ответ дан Rob 19 August 2018 в 16:57
поделиться
  • 1
    Закрывает ли закрытие group.notify как обработчик завершения после завершения обеих задач, добавленных в группу? Кроме того, когда мы вводим замыкания в группу, как это известно, чтобы приостановить выполнение, пока мы не закончим добавление всех наших запросов? Я спрашиваю, потому что, если он заканчивает первый запрос, прежде чем я добавлю свою вторую, и вызовы уведомляют, а вторая все еще ожидает. Это вообще не проблема? – Eman H 16 September 2016 в 18:26
  • 2
    Да, замыкание вызывается, когда все вызовы enter были сбалансированы с соответствующими вызовами leave. Таким образом, только после того, как все вызовы leave будут получены, будет вызываться блок группы отправки notify. – Rob 16 September 2016 в 18:28
  • 3
    Приношу свои извинения за шквал вопросов, но разве это не означает, что первая функция покидает группу, а уведомление вызывается до того, как вторая функция будет введена в группу? – Eman H 16 September 2016 в 22:07
  • 4
    Теоретически возможно , но при работе с асинхронными запросами это крайне маловероятно. И неважно, если это произойдет, потому что notify находится в конце, и в этот момент было два вызова enter, и поэтому группа не выдаст notify, пока не будет два leave. Эта картина прочная. Просто убедитесь, что вы не вызываете notify до тех пор, пока вы не вызвали все необходимые требования enter: если вы это сделаете, он не будет выполнять блок notify до тех пор, пока все соответствующие leave вызовы не будут выполнены , – Rob 16 September 2016 в 22:12
  • 5
    @Rob Я пытаюсь использовать группы отправки для повторения с асинхронным запросом. Я не уверен, как заблокировать условие цикла while от проверки до тех пор, пока я не получу ответ от предыдущего вызова. Это что-то, что может быть сделано с группами отправки или есть лучший подход, который вы бы посоветовали stackoverflow.com/questions/41810233/… – user2363025 24 January 2017 в 01:33

Источник: Как написать dispatch_after GCD в Swift 3? Для этого вы можете использовать dispatch_group. Например (код ObjC):

dispatch_group_t group = dispatch_group_create();

//startOperation1
dispatch_group_enter(group);

//finishOpeartion1
dispatch_group_leave(group);


//startOperation2
dispatch_group_enter(group);

//finishOpeartion2
dispatch_group_leave(group);


//Handle both operations completion
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
//code here
});
-1
ответ дан Community 19 August 2018 в 16:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: