Skip to content

Instantly share code, notes, and snippets.

@Grubba27
Last active March 4, 2024 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Grubba27/18355758676435f4868aabc03aa816e2 to your computer and use it in GitHub Desktop.
Save Grubba27/18355758676435f4868aabc03aa816e2 to your computer and use it in GitHub Desktop.
Async/Await implementation in Go with generics for better IDE support
package async
// This snippet is an update on what we see in
// https://hackernoon.com/asyncawait-in-golang-an-introductory-guide-ol1e34sg
// Also this one follows this assumptions from this article: https://appliedgo.net/futures/
// Assumption #1: It is ok that the spawned goroutine blocks after having calculated the result.
// Assumption #2: The reader reads the result only once.
// Assumption #3: The spawned goroutine provides a result within a reasonable time.
import "context"
type future[K any] struct {
await func(ctx context.Context) K
}
type Fiber[K any] interface {
Await() K
AwaitWithContext(ctx context.Context) K
}
func (f future[K]) Await() K {
return f.await(context.Background())
}
func (f future[K]) AwaitWithContext(ctx context.Context) K {
return f.await(ctx)
}
func Future[K any, F func() K](f F) Fiber[K] {
var r K
ch := make(chan struct{})
go func() {
defer close(ch)
r = f()
}()
return future[K]{
await: func(ctx context.Context) K {
select {
case <-ch:
return r
case <-ctx.Done():
return r
}
},
}
}
/// main.go
package main
import (
"fmt"
"main/async"
"time"
)
func DoneAsync() int {
fmt.Println("Warming up ...")
time.Sleep(3 * time.Second)
fmt.Println("Done ...")
return 1
}
func main() {
fmt.Println("Let's start ...")
future := async.Future(DoneAsync)
fmt.Println("Done is running ...")
val := future.Await()
fmt.Println(val)
}
@Grubba27
Copy link
Author

Grubba27 commented Mar 4, 2024

Screenshot 2024-03-03 at 21 35 57

Here is IDE support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment