一尘不染

Swift Function从异步Firebase调用返回值

swift

我正在编写一个函数,该函数采用groupchatID(字符串),并为该群聊返回收件人列表([String])。我正在努力与功能的异步部分。当我运行该函数时,它将正确地将我要查找的用户名数组打印到控制台。虽然,当我调用该函数并尝试打印返回的值时,它始终是一个空数组,因为该函数会在Firebase调用完成之前返回该数组。我正在尝试使用回调,但是我不太了解所有语法。请看一下,让我知道需要更改的内容。

功能:

func GetRecipientsFor(GroupChatID :String , completion: @escaping ([String]) -> ()) {
var returnArray: [String] = [""]
rootRef.child("chatMembers").child(GroupChatID).observeSingleEvent(of: .value, with: { (snapshot) in
    for child in snapshot.children.allObjects {
        var append = child as! FIRDataSnapshot
        returnArray.append((append.key as String))
        print("Return Array Currently Contains: \(returnArray)")
        //The above printout works properly and when the for loop finishes, the array is exactly as I want it
    }
    completion(returnArray)
    //BUT, this portion returns an empty array
})
}

我如何调用该函数:

GetRecipientsFor(GroupChatID: gchatID) { (result) -> () in
        print(result)
    }

新功能调用

var recipients : [String] = [""]
DispatchQueue.main.async {
    GetRecipientsFor(GroupChatID: gchatID) { result in
    print(result) //PRINTS CORRECTLY!!!
    recipients = result
    }
}
print(recipients) //PRINTS A BLANK ARRAY

阅读 207

收藏
2020-07-07

共1个答案

一尘不染

问题所在

var recipients : [String] = [""]
DispatchQueue.main.async {
    GetRecipientsFor(GroupChatID: gchatID) { result in
    print(result)
    recipients = result
    }
}
print(recipients) // Completes before recipients = result

是最后一行发生在异步调用之前。

解释以后还会print(recipients)发生recipients = result。使用接收者的所有逻辑都需要在该完成块内发生。您需要做的就是

func getRecipients(completion: @escaping ([String]) -> ()) {
    var recipients : [String] = [""]
    DispatchQueue.main.async {
        GetRecipientsFor(GroupChatID: gchatID) { result in
        print(result)
        completion(result)
        }
    }
}

如果您想包含更多的逻辑,则可以在完成时调用一个函数,即handleResults(result)。我认为,阅读有关闭包/补全块/和异步调用的更多信息将非常有益。

2020-07-07