You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jun 19, 2019. It is now read-only.
This is not really an issue, but more of a design problem.
I typically use channels to coordinate the asynchronous corner of an app.
My question is how do I design an async response (either succes or error) and put it on a channel?
I came up with something like
// renamed `dispatch` to `go`go{letchans=fetchLogin(user)// fetch login calls my api and returns a tuple: fetchlogin(user: User) -> (Chan<Error>, Chan<User>)_select{_case(chans.0){ err in/*do stuff with the error*/}_case(chans.1){ resp in/*do stuff with the success response*/}}}
I have no idea if this is an elegant solution, I'm coming from dynamic languages where I could just put both an error and a valid response on one channel, then I would determine if it was an error or valid response when taking the value from the channel. Here channels are typed, I can't put both on the same channel. I just put them on different channels.
The current 'best practice' with Swift is designing an Enum:
I'm not aware of an official Swift way to handle this issue, but I don't recommend returning multiple channels in a tuple. Though it's possible to make this work, I believe the fewer the channels the cleaner the code.
One approach that I've used many times in the Golang environment in the past is to return a single custom type that contains both the error and response values.
For example, let say you have a User type and a method named login which does work in the background.
classUser{varid:String=""}enumLoginError:ErrorType{case Success
case Failed
}structLoginResponse{varuser:Uservarerror:LoginError}func login(username:String, password:String)->Chan<LoginResponse>{letch=Chan<LoginResponse>()dispatch{// do some login magic in the backgroundletuser=User()
if username !="user" || password !="password"{
ch <-LoginResponse(user: user, error:.Failed)return}
user.id ="1234"
ch <-LoginResponse(user: user, error:.Success)}return ch
}
In the foreground, or perhaps from another dispatch routine...
letch=login("user", password:"password")letresp=<-ch
if resp!.error !=.Success {print("login failed", resp!.error)return}print("login success", resp!.user.id)
I'm sure there are multiple ways to handle this. But this seems the easiest to understand for myself.
Also this example show a way to have an enum in the Channel.
First of all great work with this library!
This is not really an issue, but more of a design problem.
I typically use channels to coordinate the asynchronous corner of an app.
My question is how do I design an async response (either succes or error) and put it on a channel?
I came up with something like
I have no idea if this is an elegant solution, I'm coming from dynamic languages where I could just put both an error and a valid response on one channel, then I would determine if it was an error or valid response when taking the value from the channel. Here channels are typed, I can't put both on the same channel. I just put them on different channels.
The current 'best practice' with Swift is designing an Enum:
I tried putting such an enum on a Channel, but Swift's type system doesn't accept it.
Any ideas? Maybe I can make it into a recipe and put it in the docs of this repo.
The text was updated successfully, but these errors were encountered: