等待两个异步完成函数完成,然后再执行下一行代码

Posted

技术标签:

【中文标题】等待两个异步完成函数完成,然后再执行下一行代码【英文标题】:wait for two asynchronous completion functions to finish, before executing next line code 【发布时间】:2016-08-26 21:57:00 【问题描述】:

我有两个函数:func Females_NonChat()func males_NonChat() 我想在 viewdidload 中执行 print 语句之前等待它们完成。我需要另一个完成处理程序来完成吗?

使用的那些函数是用于从在线数据库请求信息的 firebase 完成处理程序...

override func viewDidLoad() 
    super.viewDidLoad()
    func Females_NonChat()
    func males_NonChat()

    print("finished executing both asynchronous functions")


func Females_NonChat()
    Anon_Ref.child("Chatting").child("female").observeSingleEventOfType(.Value, withBlock: (snapshot) in
        if let FemInChatting = snapshot.value as? [String : String] 
            print("executing")
        
    )


func males_NonChat()
    Anon_Ref.child("Chatting").child("male").observeSingleEventOfType(.Value, withBlock: (snapshot) in
        print("executing")
    )

【问题讨论】:

您的viewDidLoad 中的func Females_NonChat(); func males_NonChat() 到底是什么?这甚至不是合法的 Swift。提供编译的代码(如果可以的话)。 我会说这是***.com/questions/11909629/… 的完全副本,它出现在“相关”列表的首位。你有没有在询问之前尝试过搜索? @matt 据我所知,我们可以在 Swift 中使用嵌套函数,所以函数内部可以包含另一个函数,不是吗? @EvgenyKarkan 你在说什么?这些不是嵌套函数。它们既不是函数声明也不是函数调用。它们是非法语法。如果他们是calls,他们不会说func。如果它们是 declarations,它们将具有 body(花括号)。 【参考方案1】:

一般你会使用一个dispatch group,在每个异步方法之前进入组,在每个异步方法完成后离开组,然后在所有“enter”调用都匹配到相应的“leave”时设置一个组通知调用:

override func viewDidLoad() 
    super.viewDidLoad()

    let group = dispatch_group_create()

    dispatch_group_enter(group)
    Females_NonChat() 
        dispatch_group_leave(group)
    

    dispatch_group_enter(group)
    males_NonChat() 
        dispatch_group_leave(group)
    

    dispatch_group_notify(group, dispatch_get_main_queue())  
        print("finished executing both asynchronous functions")
    


func Females_NonChat(completionHandler: () -> ()) 
    Anon_Ref.child("Chatting").child("female").observeSingleEventOfType(.Value)  snapshot in
        if let FemInChatting = snapshot.value as? [String : String] 
            print("executing")
        
        completionHandler()
    


func males_NonChat(completionHandler: () -> ()) 
    Anon_Ref.child("Chatting").child("male").observeSingleEventOfType(.Value)  snapshot in
        print("executing")
        completionHandler()
    

【讨论】:

我正在尝试这个,但由于某种原因我的函数没有被调用。我也必须在某个地方给他们打电话吗? 发现了问题。问题是,在您的代码中,您使用 dispatch_group_enter 块创建函数 你说的是func males_NonChat(),但应该是males_NonChat() 同意。修改后的答案。 你能看看这个。试图遵循你的逻辑:***.com/questions/39465789/…【参考方案2】:

这是一个执行两个异步方法并在两者都完成时打印的示例。

尝试将此代码复制到 Swift Playground 中并运行它。

import Foundation

func doTwoThings() 
    var thing1Done: Bool = false
    var thing2Done: Bool = false

    func done() 
        if thing1Done && thing2Done 
            print("Both things done! at \(getTime())")
        
    

    doThing1(completionHandler: 
        thing1Done = true
        done()
    )

    doThing2(completionHandler: 
        thing2Done = true
        done()
    )


func doThing1(completionHandler: @escaping () -> Void) 
    print("Starting Thing 1 at \(getTime())")
    Timer.scheduledTimer(withTimeInterval: 3, repeats: false, block: _ in
        print("Done with Thing 1 at \(getTime())")
        return completionHandler()
    )


func doThing2(completionHandler: @escaping () -> Void) 
    print("Starting Thing 2 at \(getTime())")
    Timer.scheduledTimer(withTimeInterval: 5, repeats: false, block: _ in
        print("Done with Thing 2 at \(getTime())")
        return completionHandler()
    )


func getTime() -> String 
    let date = Date()
    let calendar = Calendar.current
    let hour = calendar.component(.hour, from: date)
    let minute = calendar.component(.minute, from: date)
    let second = calendar.component(.second, from: date)
    return "\(hour):\(minute):\(second)"


doTwoThings()

输出:

Starting Thing 1 at 11:48:51
Starting Thing 2 at 11:48:51
Done with Thing 1 at 11:48:54
Done with Thing 2 at 11:48:56
Both things done! at 11:48:56

【讨论】:

以上是关于等待两个异步完成函数完成,然后再执行下一行代码的主要内容,如果未能解决你的问题,请参考以下文章

等待函数首先执行,然后再移动到下一行代码

同步/异步 异步回调 协成 线程队列

JS基础--EventLoop

在映射下一项之前,异步等待映射不等待异步函数在映射函数内部完成

JavaScript 异步操作之回调函数

如何调用异步函数