Я пытаюсь использовать DispatchQueue, чтобы мой код ждал, пока запрос не получит нужные мне результаты из Cloud Firestore, прежде чем он продолжит выполнение, но просто не смог заставить его работать. В приведенном ниже коде я пытаюсь заставить его ждать, пока данные не будут получены и сохранены в zoneMarkerArray, а затем распечатать результат.
Я пронумеровал каждую строку, которую он печатает, в том порядке, в котором я хочу, чтобы это происходило, и, как вы увидите в выводе, он не ждет результата Firestore, прежде чем двигаться дальше.
Вот мой код:
let zones = self.db.collection("zones")
let zonesQuery = zones.whereField("start", isGreaterThan: lowerLimit).whereField("start", isLessThan: upperLimit)
print("1. zones Query has been defined")
//pass zonesQuery query to getZoneMarkers function to retrieve the zone markers from Firestore
getZoneMarkers(zonesQuery)
print("6. Now returned from getZoneMarkers")
func getZoneMarkers(_ zonesQuery: Query) -> ([Double]) {
print("2. Entered getZoneMarkers function")
DispatchQueue.global(qos: .userInteractive).async {
zonesQuery.getDocuments() { (snapshot, error) in
if let error = error {
print("Error getting zone markers: \(error)")
} else {
print("3. Successfully Retrieved the zone markers")
var result: Double = 0.0
for document in snapshot!.documents {
print("Retrieved zone marker is \(document["start"]!)")
self.zoneMarkerArray.append(document["start"]! as! Double)
print("4. Looping over zone marker results")
}
}
}
DispatchQueue.main.async {
//I want this the printCompleted function to print the result AFTER the results have been retrieved
self.printCompleted()
}
}
return self.zoneMarkerArray
}
func printCompleted() {
print("5. Looping now completed. Result was \(zoneMarkerArray)")
}
И вот вывод, который распечатывает:
- зоны Запрос определен
- Введена функция getZoneMarkers
- Теперь возвращено из getZoneMarkers
- Зацикливание завершено. Результат был [0.0]
- Успешно получены маркеры зон
- Перебор результатов маркера зоны
- Перебор результатов маркера зоны. Полученный маркер зоны равен 12,0.
- Перебор результатов маркера зоны
Спасибо за помощь!
РЕДАКТИРОВАТЬ: Если кто-то еще борется с этим, вот рабочий код, который я собрал в конце на основе полученных отзывов. Пожалуйста, не стесняйтесь критиковать, если вы видите, как это можно улучшить:
let zones = self.db.collection("zones")
let zonesQuery = zones.whereField("start", isGreaterThan: lowerLimit).whereField("start", isLessThan: upperLimit)
print("1. zones Query has been defined")
//pass zonesQuery query to getZoneMarkers function to retrieve the zone markers from Firestore
getZoneMarkers(zonesQuery)
func getZoneMarkers(_ zonesQuery: (Query)) {
print("2. Entered getZoneMarkers function")
zoneMarkerArray.removeAll()
zonesQuery.getDocuments(completion: { (snapshot, error) in
if let error = error {
print("Error getting zone markers: \(error)")
return
}
guard let docs = snapshot?.documents else { return }
print("3. Successfully Retrieved the zone markers")
for document in docs {
self.zoneMarkerArray.append(document["start"]! as! Double)
print("4. Looping over zone marker results")
}
self.completion(zoneMarkerArray: self.zoneMarkerArray)
})
}
func completion(zoneMarkerArray: [Double]) {
print("5. Looping now completed. Result was \(zoneMarkerArray)")
}
DispatchQueue.main.async
, вероятно, должен быть внутри закрытияzonesQuery.getDocuments()
- person MadProgrammer   schedule 11.02.2020return
использовать асинхронный метод. Даже если вы правильно реализовали ожидание, есть большая вероятность, что вы в конечном итоге заблокируете основную очередь. Вы должны передать закрытие завершения в свою функциюgetZoneMarkers
и передать, а затем вызвать это закрытие с вашими полученными маркерами. См. stackoverflow.com /вопросы/25203556/ - person Paulw11   schedule 11.02.2020