The async
package provides interfaces and utilities for writing asynchronous code in Go.
This is an experimental package which has a similar API as fillmore-labs.com/promise, but is implemented with a structure instead.
Assuming you have a synchronous function func getMyIP(ctx context.Context) (string, error)
returning your external IP
address (see GetMyIP for an example).
Now you can do
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
query := func() (string, error) {
return getMyIP(ctx) // Capture context with timeout
}
future := async.NewAsync(query)
and elsewhere in your program, even in a different goroutine
if ip, err := future.Await(ctx); err == nil {
slog.Info("Found IP", "ip", ip)
} else {
slog.Error("Failed to fetch IP", "error", err)
}
decoupling query construction from result processing.
Sample code to retrieve your IP address:
const serverURL = "https://httpbin.org/ip"
func getMyIP(ctx context.Context) (string, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, serverURL, nil)
if err != nil {
return "", err
}
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer func() { _ = resp.Body.Close() }()
ipResponse := struct {
Origin string `json:"origin"`
}{}
err = json.NewDecoder(resp.Body).Decode(&ipResponse)
return ipResponse.Origin, err
}
- Futures and Promises in the English Wikipedia