简体   繁体   English

在返回之前等待完成处理程序完成

[英]Wait for completion handler to finish before returning

    func checkUsername(username: String) -> Bool {
        var avalible = true
        
        Database.database().reference().child("usernames").child(username).observeSingleEvent(of: .value, with: { snapshot in
            if snapshot.exists() {
                print("exists")
                avalible = false
            }
        })
        
        return available
    }

I'm trying to check if a username exists.我正在尝试检查用户名是否存在。
I've already tried multiple things, but it seems like the function always returns before the completion handler even finishes and always gives the same output (true) even if the username is already taken.我已经尝试了多种方法,但似乎 function 总是在完成处理程序完成之前返回,并且即使用户名已被使用,也总是给出相同的 output (true)。

Does somebody have an idea how to „wait“ for the completion handler first to finish before returning the „available“ variable?有人知道如何在返回“可用”变量之前先“等待”完成处理程序完成吗?

An explanation with the answer would be excellent.有答案的解释会很好。
Thanks.谢谢。

You cannot return something from an asynchronous task.您不能从异步任务中返回一些东西。 Your code – with fixed typos – returns true even before the database request has been started.您的代码 - 带有固定拼写错误 - 甚至在数据库请求开始之前就返回true

Maybe there is a native async/await version of observeSingleEvent but in any case you can use a Continuation也许有一个原生的 async/await 版本的observeSingleEvent但在任何情况下你都可以使用Continuation

func checkUsername(username: String) async -> Bool {
    return await withCheckedContinuation { continuation in
        Database.database().reference().child("usernames").child(username).observeSingleEvent(of: .value, with: { snapshot in
            continuation.resume(returning: !snapshot.exists())
        })
    }
}

And call it并称之为

Task {
   let isAvailable = await checkUsername(username: "Foo")

}

This is because the Firebase operation is asynchronous, you cannot simply turn that into a synchronous operation without blocking the thread.这是因为 Firebase 操作是异步的,您不能简单地将其转换为同步操作而不阻塞线程。

Have a look at How could I create a function with a completion handler in Swift?看看我如何在 Swift 中创建一个带有完成处理程序的 function?

The correct way to approach this, without the use of the new async/await syntax, is to use a completion handler yourself.在不使用新的 async/await 语法的情况下,解决这个问题的正确方法是自己使用完成处理程序。

func checkUsername(username: String, completion: @escaping (Bool) -> ()) {
    Database.database().reference().child("usernames").child(username).observeSingleEvent(of: .value) { snapshot in
         completion(!snapshot.exists())
    }
}

// To use:
checkUsername(username: "foo") { exists in 
    print("exists? ", exists)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在继续之前等待 getDownloadURL 完成? - How to wait for getDownloadURL to finish before proceeding? 如何在执行任务之前等待多个 firebase 查询完成? - How to wait for multiple firebase queries to finish before executing a task? 如何等到从 Firebase 下载完成后才执行完成 swift - How to wait till download from Firebase Storage is completed before executing a completion swift 如何确保一个 Firebase 查找的完成处理程序在另一个查找之前完成 - How to ensure Completion handler for one Firebase lookup completes before another one does Firestore promise 在返回产品之前等待产品详细信息 - Firestore promise wait for product details before returning products 在 Flutter 中呈现小部件之前,如何等待异步 function 完成执行 - How do I wait for an async function to finish executing before rendering a widget in Flutter 如何在不同的 class 中调用 table.reloadData 之前实现 Firebase 更新的完成处理程序? - How to implement a completion handler for Firebase update before table.reloadData is called in a different class? 运行命令扩展执行正在进行中。 在调用运行命令之前请等待完成 - Run command extension execution is in progress. Please wait for completion before invoking a run command Firebase/Firestore 的完成处理程序不起作用 - Completion Handler for Firebase/Firestore not working 如何在发回响应之前等待 python lambda 处理程序中的所有事件? - How to wait for all events in a python lambda handler before sending back a response?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM