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

Posted

技术标签:

【中文标题】如何处理 Swifty JSON Alamofire 请求中的优先级?【英文标题】:How to handle priorities in a Swifty JSON Alamofire request? 【发布时间】:2020-04-12 03:09:28 【问题描述】:

如何在 javascript 中使用 dispatchQueue 或类似“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)

提前谢谢你!

【问题讨论】:

【参考方案1】:

标准模式是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 闭包的参数以匹配与您的情况相关的任何内容。

但是不要迷失在上面例子的细节中,而应该只关注几个关键的观察结果:

    提供完成处理程序闭包以在所有请求完成时调用。 使用DispatchGroup 跟踪所有请求的完成时间。 为您的DispatchGroup 提供一个notify 闭包,当所有group.enter() 调用被各自的group.leave() 调用抵消时,该闭包将被调用。 更微妙的观察是,您应该避免从responseJSON 块中更新属性。在您的异步代码中,如果可能的话,您真的希望将您的交互限制在局部变量中。将结果传回 completion 闭包(调用者可以根据需要更新模型和 UI)。

【讨论】:

以上是关于如何处理 Swifty JSON Alamofire 请求中的优先级?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理空的 JSON 对象?

JSON Codable - 如何处理 [Any]?

如何处理需要反透视的 JSON 数据?

如何处理 JSON 数据的多个链接?

如何处理多个单独的 json 响应?

如何处理具有多个 tsconfig.json 文件的项目?