Это работает как задумано / задокументировано, но если вы никогда не использовали асинхронный API, это действительно может сбить с толку. Причина того, что код выполняется не по порядку, заключается в том, что postDoc.getDocuments()
должен считывать данные с сервера, что может занять некоторое время. Вместо того, чтобы блокировать ваш код (и, таким образом, удерживать пользователя от использования вашего приложения), ваш основной код может продолжаться. И затем, когда данные доступны с сервера, ваш обработчик завершения вызывается с этими данными.
Проще всего это увидеть, добавив несколько операторов регистрации:
print("Before starting to load data")
let postDoc = db.collection("announcement")
postDoc.getDocuments { (querySnapshot, err) in
print("Got data");
}
print("After starting to load data")
Когда вы запустите это минимальный код, он печатает:
Перед началом загрузки данных
После начала загрузки данных
Получил данные
Это работа по назначению, но на самом деле очень запутанная, если вы еще никогда не работали с асинхронными или управляемыми событиями API. К сожалению, большинство современных облачных / веб-API являются асинхронными, поэтому лучше всего привыкнуть к этому шаблону. Надеюсь, мои объяснения, приведенные выше, немного помогут в этом.
Две важные вещи, которые нужно запомнить:
- Ваш
print(docSecond)
не печатает нужные данные, потому что docSecond.append(max)
hasn ' пока не выполняется. - Любой код, которому нужны данные из базы данных, должен находиться внутри обработчика завершения, который вызывается с этими данными (или вызывается оттуда).
You не может вернуть данные, которые загружены асинхронно. Типичным обходным решением является создание пользовательского обработчика завершения, очень похожего на обработчик завершения, который Firestore getDocuments()
принимает postDoc.getDocuments { (querySnapshot, err) in
, но затем с вашим собственным типом.
Что-то вроде:
func getThirtyData(_ completion: (Array<Int>) -> ()) {
var querySecond = [Int]()
var docSecond = [Int]()
let postDoc = db.collection("announcement")
postDoc.getDocuments { (querySnapshot, err) in
if let err = err{
print("Error getting documents: \(err)")
}else{
for document in querySnapshot!.documents{
querySecond.append(document.data()["postTimeSecondInt"] as! Int)
}
for _ in 1...querySecond.count{
let max = querySecond.max()!
docSecond.append(max)
let index = querySecond.firstIndex(of: max)
querySecond.remove(at: index!)
}
completion(docSecond)
}
}
}
А затем назовите это как:
getThirtyData { docSecond in
getDataContent(thirtyData: docSecond)
}
См. Также: