Go并发模式之 错误处理

不好的处理错误方式,或者说 没有进行错误处理的例子:
func main() {
	checkStatus := func(done <-chan interface{}, urls ...string) <-chan *http.Response{
		responses := make(chan *http.Response)

		go func() {
			defer close(responses)
			for _, url := range urls{
				resp, err := http.Get(url)
				if err != nil {
					fmt.Println(err)
					continue
				}

				select{
					case <- done :
						return
					case responses <- resp:
				}
			}

		}()

		return responses
	}

	done := make(chan interface{})
	defer close(done)
	urls := []string{"https://www.baidu.com", "https://badhost"}
	for response := range checkStatus(done, urls...) {
		fmt.Printf("Response: %v\n", response.Status)
	}

}

*/
//Response: 200 OK
//Get https://badhost: dial tcp: lookup badhost: no such host
建议: 一般来说,你的并发进程应该把它们的错误发送到你的程序的另一个部分,他有你的程序状态的完整信息,并可以作出更明智的决定。

下面是正确的解决方案:
func main(){
	type Result struct{
		Error error
		Response *http.Response
	}

	checkStatus := func(done <-chan interface{}, urls ...string) <-chan Result {
		results := make(chan Result)
		go func() {
			defer close(results)
			for _, url := range urls{
				var result Result
				resp, err := http.Get(url)
				result = Result{Error:err, Response:resp}
				select{
					case <-done :
						return
					case results <- result :
				}
			}

		}()
		return results
	}

	done := make(chan  interface{})
	defer close(done)
	urls := []string{"https://www.baidu.com", "https://badhost"}
	for result := range checkStatus(done, urls...){
		if result.Error != nil {
			fmt.Printf("error:%v", result.Error)
			continue
		}
		fmt.Printf("Response:%v \n", result.Response.Status)
	}
}
分析: 已经成功地将 错误处理的担忧从 生产者goroutine 中分离出来。这是可取的!对的!。
因为goroutine 的goroutine (在这里就是 main goroutine了)具有更多 关于运行的程序上下文,
并且可以做出关于如何处理错误的更明智的决定。

上面例子; 还可以稍微修改程序 ,可以做其他的事。如: 在 出现三个或更多错误时,停止 checkStatus

在构建从goroutine 返回值时,应将错误视为一等公民。 如果你的goroutine可能产生错误,那么这些错误应该与你的结果紧密结合起来,
并且通过相同的通信 传递。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值