Как обрабатывать приоритеты в запросе Swifty JSON Alamofire? - PullRequest
0 голосов
/ 12 апреля 2020

Как я могу использовать dispatchQueue или что-то вроде «await» в Javascript, чтобы вернуть значение в self.arrayData (потому что конец моего l oop запускается перед предыдущим содержимым). Я привык к R и Python, где код работает строка за строкой. Какое поведение лучше всего использовать в Swift?

Вот функция:

func fetch2(){

    var i:Int = 0

    repeat {

    AF.request(itemLookUp[i]).validate().responseJSON { response in

    switch response.result {

    case .failure(let error):
    print("\(error) in fetch2")

    case .success(let value):

        let json = JSON(value)

        //Extract the Matiere for ML Extraction
    self.matiereInput = json["ResultSet"]["0"]["Result"]["0"]["SpAdditional"].string ?? "none"

        let energyCheck:Bool = self.matiereInput.contains("エネルギー") //energy-kcal

    if energyCheck==true && self.arrayData[0]==0.0{
        //regular expression
        var patEnergy = #"(エネルギー)(([^\d]+)(\d+)(\.)(\d+)|([^\d]+)(\d+))"# //avoid the repetition of the pattern within the same matiereinput
        let patEnergy2 = self.matches(for: patEnergy, in: self.matiereInput)
        patEnergy = patEnergy2.joined(separator:"")
        let valueEnergy = self.matches(for: self.regex2, in: patEnergy)
        self.arrayData[0] = Double(valueEnergy.joined(separator: "")) ?? 0.0
        }

    }
        }
        i = i+1
        print(self.arrayData[0])
} while i <= (self.returned-1)
}

Заранее спасибо!

1 Ответ

1 голос
/ 12 апреля 2020

Стандартный шаблон - notify с DispatchGroup, а затем используйте обработчик завершения для асинхронного уведомления вызывающей стороны о результате:

func fetchAll(completion: @escaping (Result<[Double], Error>) -> Void) {
    let group = DispatchGroup()

    var results: [Double] = []
    var errors: [Error] = []

    for item in lookupItems {
        group.enter()                                          // enter before request

        AF.request(item).validate().responseJSON { response in
            defer { group.leave() }                            // leave when this closure is done

            switch response.result {
            case .failure(let error):
                errors.append(error)

            case .success(let value):
                let result = ...
                results.append(result)
            }
        }
    }

    group.notify(queue: .main) {
        if let error = errors.first {                          // I don’t know what you want to do if there were multiple errors, so for now I’ll just grab the first one
            completion(.failure(error))
        } else {
            completion(.success(results))
        }
    }
}

И тогда вы будете использовать его следующим образом:

fetchAll { result in
    switch result {
    case .failure(let error):
        print(error)

    case .success(let values):
        print(values)
    }
}

Теперь я не смог перепроектировать то, что вы пытались сделать (похоже, вы обновляете self.arrayData[0] на каждой итерации!), Поэтому я просто возвратил массив Double , Но вы, очевидно, можете изменить тип results и параметр закрытия completion, чтобы он соответствовал тому, что имеет значение в вашем случае.

Но не заблудитесь в деталях приведенного выше примера, но достаточно просто сосредоточиться на нескольких ключевых наблюдениях:

  1. Закрытие обработчика завершения подачи для вызова, когда все запросы выполнены.
  2. Используйте DispatchGroup, чтобы отслеживать, когда все запросы готово.
  3. Предоставьте notify закрытие для вашего DispatchGroup, который будет вызываться, когда все вызовы group.enter() компенсируются соответствующими group.leave() вызовами.
  4. Более тонкое наблюдение Вы должны воздерживаться от обновления свойств из блока responseJSON. В вашем асинхронном коде вы действительно хотите ограничить свое взаимодействие локальными переменными, если это вообще возможно. Передайте результат обратно в закрытие completion (и вызывающая сторона может обновить модель и пользовательский интерфейс по своему усмотрению).
...