【问题标题】:Detecting a completion of async block of code - swift 4检测异步代码块的完成 - swift 4
【发布时间】:2018-06-21 00:02:11
【问题描述】:

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

这是源代码。

  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 子句永远不会被执行。 “false”值永远不会从函数中转义。如果我尝试将 if 语句移到转义闭包之外,它会在函数完成之前执行 if 语句。

【问题讨论】:

  • 你用的是什么数据库库?
  • 显示您如何称呼doesDmExist
  • 使用 completion 闭包 - 虽然它确实应该被调用,即使 existsfalse
  • 我正在使用 Firebase

标签: swift escaping closures sequence


【解决方案1】:

首先,更新您发布的代码以调用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
}

【讨论】:

  • 因为我只在数据存在时才转义(true),所以完成块中的 else 子句永远不会执行。如果我尝试将 if 语句移到阻塞的完成之外。它在函数完成之前执行。
  • 您需要更改的唯一代码是删除您调用completion(exists)if (exists)。其他一切都保持不变。
猜你喜欢
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多