GoLang FanIn功能不起作用

时间:2015-01-16 04:19:54

标签: concurrency go

所以我正在尝试使用Rob Pike的fanin函数编写一个webcrawler。

这是我的代码 -

package main
import (
    "net/http"
    "encoding/json"
    "fmt"
    "io/ioutil"
)


func main() {
   fanIn(getDuckDuckGo("food"), getGitHub("defunkt"))

}

type DuckDuckGoResponse struct {
    RelatedTopics []struct {
        Result string `json:"Result"`
        FirstUrl string `json:"FirstURL"`
        Text string `json:"Text"`
    } `json:"RelatedTopics"`
}

type GitHubResponse struct {
    Login string `json:"login"`
    Email string `json:"email"`
    Name string `json:"name"`
}

func fanIn(input1 <-chan DuckDuckGoResponse, input2 <-chan GitHubResponse) <-chan string {
    c := make(chan string)
    go func() {
        for {
            select {
            case s := <-input1:
                fmt.Println(s)
            case s := <-input2:
                fmt.Println(s)
            }
        }
    }()
    return c
}


func getDuckDuckGo(k string) <-chan DuckDuckGoResponse {
    resp, err := http.Get("http://api.duckduckgo.com/?q=" + k + "&format=json&pretty=1")
    if err != nil {
        return nil
    }
    c := make(chan DuckDuckGoResponse)
    var duckDuckParsed DuckDuckGoResponse
    jsonDataFromHttp, jsonErr := ioutil.ReadAll(resp.Body)

    if jsonErr != nil {
        fmt.Println("Json error!")
    }
    defer resp.Body.Close()


    if err:= json.Unmarshal(jsonDataFromHttp, &duckDuckParsed); err != nil {
        panic(err)
    }
    return c
}

func getGitHub(k string) <-chan GitHubResponse {
    resp, err := http.Get("https://api.github.com/users/?q=" + k)
    if err != nil {
        return nil
    }
    c := make(chan GitHubResponse)

    var githubParsed GitHubResponse
    jsonDataFromHttp, jsonErr := ioutil.ReadAll(resp.Body)

    if jsonErr != nil {
        fmt.Println("Json error!")
    }

    defer resp.Body.Close()

    if err:= json.Unmarshal(jsonDataFromHttp, &githubParsed); err != nil {
        panic(err)
    }
    return c
}

我运行这个程序,没有任何打印。

为什么?

由于

1 个答案:

答案 0 :(得分:0)

乍一看,fanIn函数返回一个未在主循环中读取的通道。所以是的,你正在调用返回一个频道的fanIn函数,但没有任何东西可以读取该频道。要使渠道有用,需要消费者消费来自渠道,而另一端则需要生产者在该渠道上生产。换句话说,发送频道无法取得进展,除非另一端有人准备接收它。

接下来,您的getGitHubgetDuckDuckGo返回频道,但他们实际上并未在他们返回的频道上发送任何内容。此外,您真正需要的是一种调用这些功能的方法,让它们返回一个频道并仍然执行您的工作。你需要使用额外的goroutine才能让http.Get调用完成他们的工作。

最后,你的fanIn功能还会创建一个频道并将其返回,但它实际上并没有&#34;扇入&#34; input1或input2的结果。由于fanIn返回一个字符串类型的通道,因此您需要在其中写入一个字符串,该字符串可以是DuckDuckGoResponseGitHubResponse之外的字段。

我恳请你们看看你想要完成的这个简化的例子:https://talks.golang.org/2012/go-docs/faninboring.go

最后一次观察您正在检查jsonErr != nil并将其打印出来,但您可能也希望返回nil以防止代码继续运行。

我希望这能为您提供足够的洞察力,让您的代码正常运行。祝你好运!