检测异步代码块的完成-Swift 4

时间:2018-06-21 00:02:11

标签: swift escaping closures sequence

我正在尝试检查数据库中是否存在数据。数据的获取是通过异步方法完成的。我需要检测函数何时完成并执行下一个代码序列。

这是源代码。

  func doesDmExist(recipientId: String, completion:@escaping (Bool) -> Void) -> Void{
    // get all the direct message rooms of the current user.
    Api.User_Chat.observeUserDirectMessage(withId: CurrentUserInfo.uid) { (dm) in
        // check if direct message exists with the given recipient id
        Api.Chat_Group.directMessageExists(chatroomId: dm, recipientId: (recipientId), completion: { (exists) in
            if(exists){
                self.dmExists = exists
                // complete.
                completion(exists)
            }
        })
    }
    // whatever I put on this line will get executed before above code is finished.
}

由于数据的获取是以异步方式完成的,所以我无法在函数末尾创建完成语句(它只会在执行上述代码之前执行完成语句)。 尽管我能够成功检测出数据是否存在,但这并不是真正有用的。我基于变量“ dmExists”的值执行代码的下一个逻辑,但是代码的下一个逻辑通常在值“ dmExists”的更新之前执行。我真的不能想到一个聪明的解决方案。有什么建议么?

这就是我调用函数的方式

 if let id = cell.user?.uid {
    doesDmExist(recipientId: id) { (flag) in
        if self.dmExists {
            print("exists")
        }else{
            print("nope")
        }
    }
}

问题在于else子句永远不会执行。永远不会从函数中逃脱“假”值。如果我尝试将if语句移到转义闭包之外,它将在函数完成之前执行if语句。

1 个答案:

答案 0 :(得分:0)

首先,更新发布的代码以调用completion,无论您为exists获得什么价值。

func doesDmExist(recipientId: String, completion:@escaping (Bool) -> Void) -> Void{
    // get all the direct message rooms of the current user.
    Api.User_Chat.observeUserDirectMessage(withId: CurrentUserInfo.uid) { (dm) in
        // check if direct message exists with the given recipient id
        Api.Chat_Group.directMessageExists(chatroomId: dm, recipientId: (recipientId), completion: { (exists) in
            self.dmExists = exists
            completion(exists)
        })
    }
}

这就是您要做的全部事情。

然后您的通话必须是这样的:

doesDmExist(recipientId: someId) { (exists) in
    // process the result as needed
}