Golang中的多个并发

I'm trying to port a simple synchronous bit of PHP to Go, but am having a hard time getting my head around how concurrency works with regards to channels. The PHP script makes a request to get a list of media library sections, then makes requests to get the items within each of these sections. If the section is a list of TV Shows, it then makes a request for each show to get all the seasons and then another to get the episodes within each season.

I've trying writing in pidgeon-go what I expected to work, but I'm not having any luck. I've tried various channel guides online, but normally end up with deadlock warnings. Currently this example warns about item := <-ch used as value and doesn't look like it's waiting on the goroutines to return. Does anyone have any ideas what I can do?

package main

import (
    "fmt"
    "time"
)

// Get all items for all sections
func main() {

    ch := make(chan string)
    sections := getSections()

    for _, section := range sections {
        go getItemsInSection(section, ch)
    }

    items := make([]string, 0)

    for item := <- ch {
        items = append(items, item)
    }

    fmt.Println(items)

}

// Return a list of the various library sections
func getSections() []string {

    return []string{"HD Movies", "Movies", "TV Shows"}

}

// Get items within the given section, note that some items may spawn sub-items
func getItemsInSection(name string, ch chan string) {

    time.Sleep(1 * time.Second)

    switch name {

    case "HD Movies":
        ch <- "Avatar"
        ch <- "Avengers"

    case "Movies":
        ch <- "Aliens"
        ch <- "Abyss"

    case "TV Shows":
        go getSubItemsForItem("24", ch)
        go getSubItemsForItem("Breaking Bad", ch)

    }

}

// Get sub-items for a given parent
func getSubItemsForItem(name string, ch chan string) {

    time.Sleep(1 * time.Second)

    ch <- name + ": S01E01"
    ch <- name + ": S01E02"

}

First, that code doesn't compile because for item := <- ch should be for item := range ch

Now the problem is you either have to close the channel or run your loop forever inside a goroutine.

go func() {
    for {
        item, ok := <-ch
        if !ok {
            break
        }
        fmt.Println(item)
        items = append(items, item)

    }
}()
time.Sleep(time.Second)
fmt.Println(items)

playground