如何处理Swifty JSON Alamofire请求中的优先级?

问题描述 投票:0回答:1

我如何使用dispatchQueue或Javascript中的诸如“ await”之类的东西来返回self.arrayData中的值(因为循环的末尾在之前的内容之前运行)。我习惯于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)
}

谢谢你!

swift alamofire grand-central-dispatch swifty-json completionhandler
1个回答
0
投票

[标准模式是带有notifyDispatchGroup,然后使用完成处理程序将结果异步通知调用者:

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闭包中(调用者可以根据需要更新模型和UI)。
© www.soinside.com 2019 - 2024. All rights reserved.