簡體   English   中英

如何使方法同步執行方法

[英]How to make a method execute methods synchronously

我嘗試使用 DispatchQueue 和 DispatchGroup 但它仍然是異步的,我也嘗試了 dispatchQueue.Async 和 dispathQueue.sync 都沒有工作。

myFunc 是在 init() 中調用的 function,它本身調用 2 個函數,getArrOneData() 和 getArrTwoData([ArrOneType])。

第一個 function 從 firestore 下載 ArrOneType 數據並返回一個初始化為字段的數組。

第二個 function 使用從第一個 function 下載的數據/字段來初始化 ArrTwoType 中的字段,同時從 firestore 下載其他相關的 ArrTwoType 數據以作為數組返回。

所以問題是它仍然是異步的。 在這種情況下如何正確使用 DispatchQueue 和 DispatchGroup?

謝謝

注意:獲取 arrTwoData 主要是偽代碼

func myFunc(){
        let group = DispatchGroup()
        let dispatchQueue = DispatchQueue.global(qos: .default)
        group.enter()
        dispatchQueue.sync {
            self.arrOne = self.getArrOneData()//getArrOneData gets data from firestore
            group.leave()
        }

dispatchQueue.sync {
        group.enter()
    self.arrTwo = self.getArrTwoData(inputArr: self.arrOne)//getArrTwoData gets data from firestore 

    group.leave()
         }
    }

//ArrOneType is an array field in ArrTwoType
func getArrTwoData(inputArr: [ArrOneType]) -> [ArrTwoType]{

var result = [ArrTwoType]()

//retrieving data from firestore, code excluded...
    for document in querySnapshot!.documents {
   let data = document.data()

name = data["Name"] as? String ?? "Name Unknown"

//returns an array which is a subset of inputArr filtered by name, however
//I dont think the inputArr is populated at this point when I run the program
var field2:[ArrOneType] = someFunc(name, inputArr)

var x = ArrTwoType(name: name, field2: field2)

result.append(x)
    }
  }
}
return result
}

如果您有兩個請求,一個使用來自一個的響應來准備下一個請求,則想法是對所有異步方法使用@escaping完成處理程序閉包,例如

func getArrayOneData(completion: @escaping (Result<[ArrayOneType], Error>) -> Void) {
    someAsynchronousMethod {
        let values: [ArrayOneType] = ...
        completion(.success(values))
    }
}

func getArrayTwoData(for typeOneValues: [ArrayOneType], completion: @escaping (Result<[ArrayTwoType], Error>) -> Void) {
    someAsynchronousMethod(for: typeOneValues) {
        let values: [ArrayTwoType] = ...
        completion(.success(values))
    }
}

然后您可以執行以下操作:

func getEverything(completion: @escaping (Result<[ArrayTwoType], Error>) -> Void) {
    getArrayOneData { result in
        switch result {
        case .failure(let error):
            print(error)

        case .success(let typeOneValues):
            getArrayTwoData(for: typeOneValues) { result in
                switch result {
                case .failure(let error):
                    print(error)

                case .success(let typeTwoValues):
                    completion(.success(typeTwoValues))
                }
            }
        }
    }
}

請注意,不需要調度組。 將完成處理程序添加到異步方法后,我們可以從第一個完成處理程序中調用第二個方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM