如何在一个功能中运行2个异步代码并逃脱它们



我想在一个函数中运行2个异步代码并逃脱它们。我希望首先下载朗诵信息,然后在这些信息中下载与朗诵者关联的图像。我正在使用Firestore。我试图与Dispatchqueue和DispatchGroup一起工作,但我无法弄清楚。我希望有人可以帮助我:)

func getReciters(completion: @escaping (Bool) -> Void) {
        var reciters = [Reciter]()
            self.BASE_URL.collection(REF_RECITERS).getDocuments { (snapchot, error) in
                if let error = error {
                    debugPrint(error)
                    completion(false)
                    // TODO ADD UIALTERCONTROLLER MESSAGE
                    return
                }
                guard let snapchot = snapchot else { debugPrint("NO SNAPSHOT"); completion(false); return }
                for reciter in snapchot.documents {
                    let data = reciter.data()
                    let reciterName = data[REF_RECITER_NAME] as? String ?? "ERROR"
                    let numberOfSurahs = data[REF_NUMBER_OF_SURAHS] as? Int ?? 0
// **HERE I WANT TO DOWNLOAD THE IMAGES**
                    self.downloadImage(forDocumentID: reciter.documentID, completion: { (image) in
                        let reciter = Reciter(name: reciterName, image: nil, surahCount: numberOfSurahs, documentID: reciter.documentID)
                        reciters.append(reciter)
                    })
                }
            }
        UserDefaults.standard.saveReciters(reciters)
        completion(true)
    }

您需要DispatchGroup

  • 在函数的范围内声明了DispatchGroup的实例。
  • 在循环中异步块调用enter
  • 在循环中内部异步块的完成处理程序call leave
  • 在循环呼叫notify之后,将在所有异步任务完成后执行关闭。

func getReciters(completion: @escaping (Bool) -> Void) {
    var reciters = [Reciter]()
    self.BASE_URL.collection(REF_RECITERS).getDocuments { (snapchot, error) in
        if let error = error {
            debugPrint(error)
            completion(false)
            // TODO ADD UIALTERCONTROLLER MESSAGE
            return
        }
        guard let snapchot = snapchot else { debugPrint("NO SNAPSHOT"); completion(false); return }
        let group = DispatchGroup()
        for reciter in snapchot.documents {
            let data = reciter.data()
            let reciterName = data[REF_RECITER_NAME] as? String ?? "ERROR"
            let numberOfSurahs = data[REF_NUMBER_OF_SURAHS] as? Int ?? 0
            group.enter()
            self.downloadImage(forDocumentID: reciter.documentID, completion: { (image) in
                let reciter = Reciter(name: reciterName, image: nil, surahCount: numberOfSurahs, documentID: reciter.documentID)
                reciters.append(reciter)
                group.leave()
            })
        }
        group.notify(queue: .main) {
            UserDefaults.standard.saveReciters(reciters)
            completion(true)
        }
    }
}

最新更新