Как заставить метод выполнять методы синхронно - PullRequest
0 голосов
/ 15 апреля 2020

Я пытался использовать DispatchQueue и DispatchGroup, но он все еще асинхронный, я также пытался использовать dispatchQueue.Asyn c и dispathQueue.syn c, но ни один из них не работал.

myFun c - это функция, вызываемая в init (), которая сама вызывает 2 функции, getArrOneData () и getArrTwoData ([ArrOneType]).

Первая функция загружает данные ArrOneType из firestore и возвращает массив, инициализированный в поле.

Вторая функция использует загруженные данные / поле из первой функции для инициализации поля в ArrTwoType, одновременно загружая другие соответствующие данные ArrTwoType из firestore для возврата в виде массива.

Таким образом, проблема заключается в том, что проблема по-прежнему асинхронная , Как правильно использовать DispatchQueue и DispatchGroup в этом сценарии?

спасибо

примечание: get arrTwoData в основном psuedocode

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
}

1 Ответ

0 голосов
/ 16 апреля 2020

Если у вас есть два запроса, один из которых использует ответ одного для подготовки следующего, идея состоит в том, чтобы использовать @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))
                }
            }
        }
    }
}

Обратите внимание, группы рассылки не нужны. Добавив обработчики завершения к асинхронным методам, мы можем просто вызвать второй метод из обработчика завершения первого.

...