如何在Golang中实现异步请求处理_使用Goroutine和Channel并发执行
技术百科
P粉602998670
发布时间:2025-12-29
浏览: 次 Go中异步请求处理的核心是goroutine启动并发任务、channel传递结果,配合sync.WaitGroup控制流程,避免闭包陷阱和死锁,并通过context超时与错误结构体保障可靠性。
在 Go 中实现异步请求处理,核心是用 goroutine 启动并发任务,再用 channel 传递结果或控制流程。它不是“模拟异步”,而是天然支持的轻量级并发模型——无需
回调、不用 Promise,写起来更直接。
用 goroutine 快速发起多个 HTTP 请求
每个请求单独起一个 goroutine,避免阻塞主线程。注意:要传参(如 URL)进 goroutine,别直接用循环变量(会闭包捕获最后值)。
- 用
go func(url string) { ... }(url)立即传值启动 - 用
http.DefaultClient.Do(req)发起请求,手动设置超时更稳妥 - 别忘了关闭响应体:
defer resp.Body.Close()
用 channel 收集结果并等待全部完成
定义一个结构体 channel(如 chan Result),每个 goroutine 执行完把结果(成功/失败、数据、错误)发进去。主 goroutine 用 for range 读取,配合 sync.WaitGroup 或 len(urls) 控制接收次数。
- 推荐用
sync.WaitGroup:启动前wg.Add(len(urls)),每个 goroutine 结束调wg.Done(),主协程用go func() { wg.Wait(); close(ch) }()关闭 channel - 避免死锁:确保所有 goroutine 都会发值,且主 goroutine 不漏读
加超时和错误处理,让异步更可靠
单个请求超时用 context.WithTimeout;整体等待超时用 select + time.After。
- 每个请求构造带 timeout 的 context:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - 主流程用
select监听 result channel 和 timeout channel,超时就提前退出 - 错误不 panic:把 error 作为字段放进 Result 结构体,统一由调用方判断
简单示例:并发抓取多个 URL
以下是最小可运行骨架(省略 import):
type Result struct {
URL string
Data []byte
Err error
}
func fetchURL(ctx context.Context, url string, ch chan<- Result) {
req, := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := http.DefaultClient.Do(req)
if err != nil {
ch <- Result{URL: url, Err: err}
return
}
defer resp.Body.Close()
data, := io.ReadAll(resp.Body)
ch <- Result{URL: url, Data: data}
}
func main() {
urls := []string{"https://www./link/5f69e19efaba426d62faeab93c308f5c", "https://www./link/ef246753a70fce661e16668898810624"}
ch := make(chan Result, len(urls))
for _, u := range urls {
go fetchURL(context.Background(), u, ch)
}
for i := 0; i < len(urls); i++ {
r := <-ch
if r.Err != nil {
log.Printf("fail %s: %v", r.URL, r.Err)
} else {
log.Printf("success %s, len=%d", r.URL, len(r.Data))
}
}}
基本上就这些。Goroutine + Channel 不是“高级技巧”,而是 Go 处理并发请求的标准姿势——写得少、跑得稳、逻辑清晰。
# ai
# 时就
# 写得
# 多个
# 再用
# http
# go
# golang
# 循环
# Error
# 并发
# String
# 并发请求
# 线程
# 异步
# 死锁
# 回调
# 时用
# 结构体
# channel
# select
# len
# 别忘了
# 闭包
# for
# background
# 主线程
# promise
# 跑得
# 不漏
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Windows10电脑怎么设置防火墙出站规则_Wi
- C++ STL算法库怎么用?C++常用算法函数(s
- C++如何使用std::async进行异步编程?(
- C#如何序列化对象为XML XmlSerializ
- Win11系统占用空间大怎么办 Win11深度瘦身
- 如何在 Django 中修改用户密码后保持会话不丢
- windows系统找不到无线网络怎么办_windo
- C++如何获取CPU核心数?(std::threa
- 如何使用Golang包导出规则_控制函数和变量可见
- 如何在 Laravel 中通过嵌套关联关系进行 o
- Win10系统怎么查看端口状态_Windows10
- Windows如何拦截2345弹窗广告_Windo
- MAC怎么解压RAR格式文件_MAC第三方解压工具
- Win11怎么开启空间音效_Windows11耳机
- 如何解决Windows时间不准的问题?(自动同步设
- Win11怎么更改任务栏位置_修改注册表将Win1
- Windows如何设置登录时的欢迎屏幕背景?(锁屏
- Win11声音太小怎么办_Windows 11开启
- Win11怎么设置屏保_Windows 11屏幕保
- 如何使用Golang实现路由分组管理_Golang
- Windows10怎样连接蓝牙设备_Windows
- php8.4xdebug无法调试怎么办_php8.
- Windows如何使用注册表查找和删除项?(reg
- Windows10系统服务优化指南_Win10禁用
- PHP怎么接收URL中的锚点参数_获取#后面参数值
- Python解释执行模型_字节码流程说明【指导】
- Win10怎么创建桌面快捷方式 Win10为应用创
- 如何使用Golang管理跨项目依赖_Golang多
- Win11怎么关闭定位服务 Win11禁止应用获取
- 如何在Golang中实现服务熔断与限流_Golan
- TestNG的testng.xml配置文件怎么写
- MAC怎么用连续互通相机里的“桌上视角”_MAC在
- Python抽象类与接口设计_规范说明【指导】
- 如何在Golang中验证模块完整性_Golangg
- LINUX怎么查看进程_LINUX ps命令查看运
- Mac版Final Cut Pro入门_Mac视频
- Win11开机自检怎么关闭_跳过Win11开机磁盘
- 如何在 Go 后端安全获取并验证前端存储的 JWT
- Win11怎么连接蓝牙耳机_Win11蓝牙设备配对
- Python装饰器复用技巧_通用能力解析【教程】
- PythonPandas数据分析项目教程_时间序列
- 如何使用Golang reflect检查方法数量_
- Linux怎么查找死循环进程_Linux系统负载分
- mac怎么打开终端_MAC终端Terminal使用
- php485能和物联网模块通信吗_php485对接
- 如何使用Golang处理网络超时错误_Golang
- c++的static关键字有什么用 静态变量和静态
- C++如何将C风格字符串(char*)转换为std
- Win11怎么快速锁屏_Win11一键锁屏快捷键W
- Mac怎么安装软件_Mac安装dmg与pkg文件的

QQ客服