简体   繁体   English

嵌套调度组

[英]Nested DispatchGroup

I try use nested DispatchGroup, there is my code : 我尝试使用嵌套的DispatchGroup,这是我的代码:

 class TranslateService {
      private let myGroup = DispatchGroup()
      func translateText(text:[String],closure:@escaping ((_ success:String?,_ error:Error?) -> Void)) {

        var translateString: String = ""
        var responseError: Error?

        for index in 0...text.count - 1 {

          let urlString = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20171105T134956Z.795c7a0141d3061b.dc25bae76fa5740b2cdecb02396644dea58edd24&text=\(text[index])&lang=fa&format=plain&options=1"
          if let allowString = Utilities.shareInstance.getQueryAllowedString(url: urlString) {
            if let url = URL(string:allowString){
                myGroup.enter()
              Alamofire.request(url).responseJSON { response in
                guard let responseData = response.data else {
                  self.myGroup.leave()
                  return
                }
                do {
                  let json = try JSONSerialization.jsonObject(with: responseData, options: [])
                  if let res = json as? [String:Any] {
                    if let code = res["code"] as? Int {
                      if code == 200 {
                        if let textArr = res["text"] as? [AnyObject] {
                          let flattArr = Utilities.shareInstance.flatStringMapArray(textArr)
                          if flattArr.count > 0 {
                            translateString += "،" + flattArr[0]
                          }
                        }
                      }
                    }
                     self.myGroup.leave()
                  }
                }catch {
                  responseError = error
                 self.myGroup.leave()
                }
              }
              self.myGroup.notify(queue: .main) {
                print("Finished all requests.")
                print(translateString)
                closure(translateString, responseError)
              }
            }
          }
        }
      }
    }

    class AddressService {
  private let translateService: TranslateService = TranslateService()
  private let myGroup = DispatchGroup()
  func fetchAddressFromGeographicalLocation(latitude: Double, longitude: Double,closure:@escaping ((_ success:String,_ name:String,_ error:Error?) -> Void)) {

    var address: String = ""
    let name: String = ""
    var responseError: Error?
    if let url = URL(string:"https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)&key=AIzaSyAdEzHZfZWyjLMuuW92w5fkR86S3-opIF0&language=fa&region=IR&locale=fa"){
       self.myGroup.enter()
      Alamofire.request(url).responseJSON { response in

        guard let responseData = response.data else {
          self.myGroup.leave()
          return
        }
        do {
          let json = try JSONSerialization.jsonObject(with: responseData, options: [])
          if let addressDic = json as? [String:Any] {
            if let result = addressDic["results"] as? [AnyObject] {
              if result.count > 0 {
                let flattRes = Utilities.shareInstance.flatMapArray(result)
                let item = flattRes[0]
                address = item["formatted_address"] as? String ?? ""
                var res = address
                if res.isContainEnglishCharachter {
                  self.myGroup.enter()
                  let resArr = res.components(separatedBy: ",")
                  var all : [String] = []
                  for item in resArr {
                    if item != " " {
                      all.append(item)
                    }}
                  self.translateService.translateText(text: all, closure: {stringAdd,error in
                    self.myGroup.enter()
                    if error != nil {
                      self.myGroup.leave()
                    }else {
                      address = stringAdd ?? ""
                      self.myGroup.leave()
                    } })
                }else {
                  self.myGroup.leave()
                }
              }
            }
          }
        }catch {
          responseError = error
          self.myGroup.leave()
        }
        self.myGroup.notify(queue: .main) {
          // print("Finished all requests.")
          closure(address, name, responseError)
          }
      }
    }
  }
}

All I want is that the myGroup I put in the class AddressService waiting for the myGroup that I put in the class TranslateService. 我想要的只是我放在AddressService类中的myGroup等待我放在TranslateService类中的myGroup。 but now self.myGroup.notify not call in the AddressService class, So closure not work. 但是现在self.myGroup.notify无法在AddressService类中调用,因此关闭无法正常工作。 How can solve this problem, Thank you for all the answers. 怎样解决这个问题,谢谢大家的解答。

I think you are over complicating it. 我认为您过于复杂了。

If I understood a bit, what you want to do is the following: 如果我有所了解,您想要做的是以下操作:

  • Get an address from the Address service. 从地址服务获取地址。
  • Translate some words of that address, one by one, using the translation service. 使用翻译服务,逐个翻译该地址的某些单词。

When using the Address service there is only one call being done, so there is no need to use Dispatch Groups at this point. 使用地址服务时,仅完成一个呼叫,因此此时无需使用调度组。 Dispatch Groups are used to synchronize more than one async call. 调度组用于同步多个异步调用。

For your Translation service you can make good use of the Dispatch groups, since you are doing calls to the service inside a for loop. 对于您的翻译服务,您可以充分利用Dispatch组,因为您正在for循环内对服务进行调用。 The problem here is, that the implementation is slightly wrong. 这里的问题是,实现有些错误。 You are setting the notification block inside the for loop, and it should be outside, so that it gets only triggered once, when all the calls inside the loop are done. 您将在for循环内设置通知块,并且该通知块应位于外部,以便在循环内的所有调用完成后仅触发一次。

So move this block outside the for loop in the Translation service: 因此,将此块移到Translation服务的for循环之外:

self.myGroup.notify(queue: .main) {
            print("Finished all requests.")
            print(translateString)
            closure(translateString, responseError)
          }

Now "Finished all requests." 现在,“完成所有请求”。 will only be printed once, when all requests are done. 完成所有请求后,仅打印一次。

In the address service you do not need dispatch groups at all. 在地址服务中,您根本不需要调度组。 Just wait until the completion block is called. 只需等待完成块被调用即可。

self.translateService.translateText(text: all, closure: {stringAdd,error in
      Everything is done here already.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM