loading...

Discussion on: JavaScript: Handling errors like Go

Collapse
iaziz786 profile image
Mohammad Aziz

I have a question, even though this blog post is about Node.js, I have a question about Go.

How can you mimic Promise.all() in Go? What would be equivalent code in Go?

async function main() {
  // Assume all db calls will return a promise
  const firstUserPromise = firstDbCall().then((res) => res);
  const secondUserPromise = secondDbCall().then((res) => res);
  const thridUserPromise = thridDbCall().then((res) => res);

  const [
    firstUserData,
    secondUserData,
    thirdUserData
  ] = await Promise.all([firstUserPromise, secondUserPromise, thirdUserPromise]);
}
Collapse
oieduardorabelo profile image
Eduardo Rabelo Author

funny enough, in Go is a little bit harder to do the exactly same!

i recommend you to go through two blog posts:

  1. Go: Concurrency Patterns: Pipelines and cancellation
  2. Go: Learn Concurrency

you will need to use channels/goroutines to achieve the same.. as said by rhymes in this thread, you will need to use WaitGroup!

there's a merge function in the documentation link of item 1 above, where using it, you can do something like this:

func makeRequest(url string) <-chan string {
    res := make(chan string)

    go func() {
        res <- "Request started..."

        _, err := http.Get(url)

        if err != nil {
            res <- "Failed."
        }

        res <- "Done!"
        close(res)
    }()

    return res
}

func main() {
    c1 := makeRequest("https://google.com/")
    c2 := makeRequest("https://twitter.com/")

    for n := range merge(c1, c2) {
        fmt.Println(n)
    }
}

running it will print:

$ go run main.go 
Request started...
Request started...
Done!
Done!

i've been using it since I discovered it :)

Collapse
theodesp profile image
Theofanis Despoudis

I think you can also use errgroup to handle errors gracefully

Collapse
iaziz786 profile image
Mohammad Aziz

This looks simple and powerful. Probably I'll have to dig deeper to understand it. Thanks for the resources.

Collapse
rhymes profile image
rhymes

You probably need to use a WaitGroup.

This is the example you can find in the documentation link:

package main

import (
    "sync"
)

type httpPkg struct{}

func (httpPkg) Get(url string) {}

var http httpPkg

func main() {
    var wg sync.WaitGroup
    var urls = []string{
        "http://www.golang.org/",
        "http://www.google.com/",
        "http://www.somestupidname.com/",
    }
    for _, url := range urls {
        // Increment the WaitGroup counter.
        wg.Add(1)
        // Launch a goroutine to fetch the URL.
        go func(url string) {
            // Decrement the counter when the goroutine completes.
            defer wg.Done()
            // Fetch the URL.
            http.Get(url)
        }(url)
    }
    // Wait for all HTTP fetches to complete.
    wg.Wait()
}
Collapse
foresthoffman profile image
Forest Hoffman

WaitGroup is awesome 🎉

Collapse
iaziz786 profile image
Mohammad Aziz

I was not aware of WaitGroup. Thanks!