Created
July 17, 2025 15:54
-
-
Save pedrobertao/8c646b7d26e4e2e152eb76e8c95bfeb3 to your computer and use it in GitHub Desktop.
promise_all_in_go.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"net/http" | |
) | |
// Result holds the result of a work function execution | |
type Result struct { | |
Result any | |
Error error | |
} | |
// httpGet performs an HTTP GET request and returns the response body as a string | |
func httpGet(url string) (string, error) { | |
resp, err := http.Get(url) | |
if err != nil { | |
return "", err | |
} | |
defer resp.Body.Close() | |
body, err := io.ReadAll(resp.Body) | |
if err != nil { | |
return "", err | |
} | |
return string(body), nil | |
} | |
// Work is a function type that returns a result and an error | |
type Work func() (any, error) | |
// Promise is a worker goroutine that executes work from a jobs channel | |
// and sends the result to a results channel | |
func Promise(id int64, jobs <-chan Work, results chan<- Result) { | |
fmt.Printf("[%d] Fechting...\n", id) | |
// Get work from the jobs channel | |
w := <-jobs | |
// Execute the work function | |
exp, err := w() | |
// Send the result to the results channel | |
results <- Result{ | |
Result: exp, | |
Error: err, | |
} | |
} | |
// PromiseAll executes all work functions concurrently and returns all results | |
func PromiseAll(works []Work) []Result { | |
// Create buffered channels for jobs and results | |
jobs := make(chan Work, len(works)) | |
results := make(chan Result, len(works)) | |
// Start a worker goroutine for each work function | |
for i := range works { | |
go Promise(int64(i+1), jobs, results) | |
} | |
// Send all work functions to the jobs channel | |
for i := 0; i < len(works); i++ { | |
jobs <- works[i] | |
} | |
// Close the jobs channel to signal no more work | |
close(jobs) | |
// Collect all results from the workers | |
res := make([]Result, len(works)) | |
for i := 0; i < len(works); i++ { | |
workDone := <-results | |
res = append(res, workDone) | |
} | |
return res | |
} | |
func main() { | |
// Execute HTTP GET requests concurrently using the Promise pattern | |
results := PromiseAll([]Work{ | |
func() (any, error) { | |
return httpGet("https://www.google.com") | |
}, | |
func() (any, error) { | |
return httpGet("https://www.amazon.com") | |
}, | |
func() (any, error) { | |
return httpGet("https://www.facebook.com") | |
}, | |
}) | |
// Print the results | |
fmt.Println(">", results) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment