即使我没有CallbackListener,我也可以使用回调流吗

发布于 2025-02-08 01:13:40 字数 1077 浏览 3 评论 0原文

我正在使用GraphQl从服务器获取数据。 SDK并非暂停,我正在尝试使用干净的体系结构。因此,我来​​到我的存储库中返回Flow,以允许用途服务器的响应。因此,我的存储库中有此代码:

override fun singUp(model: SignUpModel): Flow<ResponseModel<SignUpServerResponse>> = callbackFlow {
            ...
          
            client.mutateGraph(signUpQuery)
                .enqueue(object : GraphCallResultCallback<Storefront.Mutation> {
                    override fun invoke(result: GraphCallResult<Storefront.Mutation>) {

                        if (result is GraphCallResult.Success) 
                            trySendBlocking(...).also { close() }
                        else 
                            trySendBlocking(...).also { close() }
                    }
                })
            awaitClose {}
        }

我的问题是:

1-每个事件后我需要致电关闭吗?显然,在从服务器中获取响应后,我不需要流动。

2-我删除了等待{},并且我发现需要此字段,并且应使用该字段来分离callbackListener,但是在这种情况下,我没有一个。如果我最后放置一个空的等待{},可以吗?

3-我知道该流程在后台使用通道。我还通过频道实施了它,我必须使用回调流吗?

I'm using GraphQL to fetch the data from the server. The SDK is not suspendable, and I'm trying to use Clean Architecture. So I came up to return a Flow in my repository to allow the UseCases to fetch the server's response. So I have this code in my repository:

override fun singUp(model: SignUpModel): Flow<ResponseModel<SignUpServerResponse>> = callbackFlow {
            ...
          
            client.mutateGraph(signUpQuery)
                .enqueue(object : GraphCallResultCallback<Storefront.Mutation> {
                    override fun invoke(result: GraphCallResult<Storefront.Mutation>) {

                        if (result is GraphCallResult.Success) 
                            trySendBlocking(...).also { close() }
                        else 
                            trySendBlocking(...).also { close() }
                    }
                })
            awaitClose {}
        }

my questions are:

1- Do I need to call the close after each event? Obviously, I don't need the flow to be alive after I fetch the response from the server.

2- I removed awaitClose {}, and I got the error that this field is required and should be used to detach the CallBackListener, but in this case, I don't have one. Is it okay if I'm putting an empty awaitClose {} at the end?

3- I know the flow uses Channels in the background. I also implemented it by channels, is there any advantages ( performance, security, etc.) that I have to using CallBackFlow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请爱~陌生人 2025-02-15 01:13:40

您不需要在此处使用callbackflow,就如注释中提到的那样。如果要使用coroutines使用singup()方法,则需要将其转换为暂停函数。要将带回调的函数转换为暂停函数suppendCoroutinesuppendCancellableCoroutine可以使用构建器。例子:

suspend fun singUp(model: SignUpModel): ResponseModel<SignUpServerResponse> = suspendCoroutine { continuation ->
        ...
      
        client.mutateGraph(signUpQuery)
            .enqueue(object : GraphCallResultCallback<Storefront.Mutation> {
                override fun invoke(result: GraphCallResult<Storefront.Mutation>) {

                    if (result is GraphCallResult.Success) 
                        continuation.resume(...) // resumes an execution of a coroutine, in which the `singUp` method was called
                    else 
                        continuation.resume(...)
                }
            })
}

You don't need to use callbackFlow here like mentioned in the comments. If you want to use singUp() method with coroutines you need to convert it to a suspend function. To convert a function, that has callbacks, to a suspend function suspendCoroutine and suspendCancellableCoroutine builders can be used. Example:

suspend fun singUp(model: SignUpModel): ResponseModel<SignUpServerResponse> = suspendCoroutine { continuation ->
        ...
      
        client.mutateGraph(signUpQuery)
            .enqueue(object : GraphCallResultCallback<Storefront.Mutation> {
                override fun invoke(result: GraphCallResult<Storefront.Mutation>) {

                    if (result is GraphCallResult.Success) 
                        continuation.resume(...) // resumes an execution of a coroutine, in which the `singUp` method was called
                    else 
                        continuation.resume(...)
                }
            })
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文