go - 如何关闭频道并等待多个 http 响应?
问题描述
我有以下内容,并且正在尝试进行一些并发的 http 调用,以便我可以加快整个程序的速度,而不是一个接一个地执行每个调用:
package main
import (
"fmt"
"net/http"
"time"
)
type U struct {
u string
name string
resp *http.Response
}
func main() {
urls := []*U{
&U{"example", "http://www.example.com", nil},
&U{"yahoo", "http://www.yahoo.com", nil},
&U{"google", "http://www.google.com", nil},
}
ch := make(chan *U)
// read from the channel
go func() {
for c := range ch {
for i, u := range urls {
if c.name == u.name {
urls[i] = c
}
}
}
}()
// fetch the stuff
for _, u := range urls {
go func(u *U) {
var err error
u, err = getResponse(u)
if err != nil {
fmt.Println(err)
}
ch <- u
}(u)
}
for i, u := range urls {
fmt.Println(i, u.resp) // all nil
}
}
func getResponse(u *U) (*U, error) {
c := &http.Client{
Timeout: 10 * time.Second,
}
var err error
u.resp, err = c.Get(u.u)
return u, err
}
https://play.golang.org/p/Zko8xkEqDMB
我显然没有在打印时做正确的事情
0 <nil>
1 <nil>
2 <nil>
而它也应该打印响应。
我如何确保等到一切都完成后才能继续前进?好的。谢谢。
解决方案
您无需等待回复返回。这相当于:
urls := []*U{
&U{"example", "http://www.example.com", nil},
&U{"yahoo", "http://www.yahoo.com", nil},
&U{"google", "http://www.google.com", nil},
}
for i, u := range urls {
fmt.Println(i, u.resp) // all nil
}
相反,您可以使用 async.WaitGroup
来确保在显示响应之前完成所有工作:
var wg sync.WaitGroup
for _, u := range urls {
wg.Add(1) // Add job to the waitgroup
go func(u *U) {
var err error
u, err = getResponse(u)
if err != nil {
fmt.Println(err)
}
ch <- u
wg.Done() // Note when the job is done
}(u)
}
wg.Wait() // wait until all the Add'd jobs are Done'd
for i, u := range urls {
fmt.Println(i, u.resp) // all nil
}
或者您可以在与以下相同的链中处理打印响应getResponse
:
for _, u := range urls {
go func(u *U) {
var err error
u, err = getResponse(u)
if err != nil {
fmt.Println(err)
}
printResponse(u) // implement printResponse however
ch <- u
}(u)
}
推荐阅读
- css - 我的 CSS 形状的圆角问题
- visual-studio-code - vscode:如何在片段*未*选择后制作文本?
- python - 用相应bin的平均值替换列中的数据?
- wordpress - 如何从wordpress中的类别url中删除类别词
- winforms - 如果用户通过关闭终端(Winforms)关闭应用程序,如何捕获关闭事件?
- python - 在 Python 中使用 api 请求时迭代 xml 正文中的页面
- reactjs - 盖茨比仅在刷新时出现
- java - 如何让 Springboot 的 ShutdownHook 等待,直到它的所有处理请求都完成?
- ag-grid - AgGridReact 的 startEditingCell 无法与自定义单元格编辑器组件一起使用
- python - 尝试 json.load Python 时出错