dongshi1102 2017-07-26 21:38
浏览 50
已采纳

执行例程:发出并发API请求

I am trying to understand channels and goroutines and tried to write a goroutine for making concurrent API requests to the server

But when I am running the code using a goroutine, it seems like it is taking the same time as it does without a goroutine.

func sendUser(user string, ch chan<- string)  {
    resp,err := http.get("URL"/user)
    //do the processing and get resp=string
    ch <- resp
}


func AsyncHTTP(users []string) ([]string, error) {
    ch := make(chan string)
    var responses []string
    var user string

    for _ , user = range users {
        go sendUser(user, ch)

        for {
            select {
            case r := <-ch:
                if r.err != nil {
                    fmt.Println(r.err)
                }
                responses = append(responses, r)
                **//Is there a better way to show that the processing of response is complete**?
                if len(responses) == len(users) { 
                    return responses, nil
                }
            case <-time.After(50 * time.Millisecond):
                fmt.Printf(".")
            }
        }
    }
    return responses, nil
}

Questions:

  1. Even though I am using a goroutine, request completion time is same as it is without goroutines? Is there anything I am doing wrong with goroutines?

  2. For telling the job not to wait anymore here I am using:

    if len(responses) == len(users)
    

    Is there a better way to show that the processing of response is complete and tell ch not to wait anymore?

  3. What is wait.Syncgroup? How can I use it in my goroutine?

  • 写回答

1条回答 默认 最新

  • douxie7738 2017-07-26 22:05
    关注

    I might do something like this..

    func sendUser(user string, ch chan<- string, wg *sync.WaitGroup) {
        defer wg.Done()
        resp, err := http.Get("URL/" + user)
        if err != nil {
            log.Println("err handle it")
        }
        defer resp.Body.Close()
        b, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            log.Println("err handle it")
        }
        ch <- string(b)
    }
    
    func AsyncHTTP(users []string) ([]string, error) {
        ch := make(chan string)
        var responses []string
        var user string
        var wg sync.WaitGroup
        for _, user = range users {
            wg.Add(1)
            go sendUser(user, ch, &wg)
        }
    
        // close the channel in the background
        go func() {
            wg.Wait()
            close(ch)
        }()
        // read from channel as they come in until its closed
        for res := range ch {
            responses = append(responses, res)
        }
    
        return responses, nil
    }
    

    It allows to read from the channel as they are sent. By using a waitgroup I'll know when to close the channel. By putting the waitgroup and close in a goroutine I can read from the channel in "realtime" without blocking.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 fluent的在模拟压强时使用希望得到一些建议
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退