2017-08-03 117 views
1

我有一個方法,當它準備好時要返回結果。但我正在與2個完成處理程序掙扎。完成處理程序問題

這是代碼。第一個完成處理程序是members.observesingleEvent。這將從數據庫中返回一些鍵。然後我循環訪問鍵以從另一個調用中獲取新值。我循環的值,並做另一個電話。

private func getRoomDevices(completionHandler : @escaping (Bool) ->()){ 


members.observeSingleEvent(of: .value, with: { snapshot in 
    if !snapshot.exists() { return } 

    let postDict = snapshot.value as! [String : AnyObject] 

    for list in postDict { 
     self.ref.child("groups/" + list.key).observeSingleEvent(of: .value, with: { groups in 
      self.rooms.append(FirebaseApi().convertRoomDevices(snap: groups)) 
      print(groups.debugDescription) 


     }); 
    } 

    completionHandler(true) 

}) 

我把所有東西加到房間數組中。但是會發生什麼情況是for循環繁忙時調用completionHandler(true)。 completionHandler需要在所有事情完成時調用。

回答

3

您必須使用DispatchGroup,您可以在其中添加異步循環中的所有項目,並且只有在組的所有項目完成執行時才調用完成處理程序。

members.observeSingleEvent(of: .value, with: { snapshot in 
    if !snapshot.exists() { return } 

    let postDict = snapshot.value as! [String : AnyObject] 
    let group = DispatchGroup() 
    for list in postDict { 
     group.enter() 
     self.ref.child("groups/" + list.key).observeSingleEvent(of: .value, with: { groups in 
      self.rooms.append(FirebaseApi().convertRoomDevices(snap: groups)) 
      print(groups.debugDescription) 
      group.leave() 
     }); 
    } 
    group.notify(queue: DispatchQueue.main) { 
     completion(true) 
    } 

})