• go 的context 使用


    1, context.WithCancel

    package main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    func main() {
    	test()
    	time.Sleep(time.Second * 5)
    }
    
    func test() {
    	ctx, cancel := context.WithCancel(context.Background())
    	defer cancel()
    
    	intChan := goroute(ctx)
    
    	for n := range intChan {
    		fmt.Println(n)
    		if n == 5 {
    			break
    		}
    	}
    }
    
    func goroute(ctx context.Context) <-chan int {
    	chanInt := make(chan int)
    	n := 1
    	go func() {
    		for {
    			select {
    			case <-ctx.Done():
    				fmt.Println("exited")
    				return
    			case chanInt <- n:
    				n++
    			}
    		}
    	}()
    	return chanInt
    }
    
    

    输出:

    1
    2
    3
    4
    5
    exited
    
    

    2, context.WithTimeout 超时控制

    package main
    
    import (
    	"context"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"time"
    )
    
    type Result struct {
    	resp *http.Response
    	err  error
    }
    
    func main() {
    	process()
    }
    
    func process() {
    	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
    	defer cancel()
    
    	tr := &http.Transport{}
    	client := &http.Client{Transport: tr}
    	chanResp := make(chan Result, 1)
    
    	//req, err := http.NewRequest("GET", "http://www.google.com", nil)
    	req, err := http.NewRequest("GET", "http://www.baidu.com", nil)
    	if err != nil {
    		fmt.Println("请求失败,err:", err)
    		return
    	}
    	go func() {
    		resp, err := client.Do(req)
    		pack := Result{
    			resp: resp,
    			err:  err,
    		}
    		chanResp <- pack
    	}()
    
    	select {
    	case <- ctx.Done():
    		tr.CancelRequest(req)
    		res := <-chanResp
    		fmt.Println("请求超时,err:", res.err)
    	case res := <-chanResp:
    		defer res.resp.Body.Close()
    		out, _ := ioutil.ReadAll(res.resp.Body)
    		fmt.Println("请求成功:")
    		//fmt.Println(string(out))  // 直接fmt.Println(out) 打印出来的是字节数代号
    		fmt.Printf("Server Response:%s",out)
    	}
    }
    
    

    输出:

    请求超时,err: Get "http://www.google.com": net/http: request canceled while waiting for connection
    

    3, context.WithValue

    package main
    
    import (
    	"context"
    	"fmt"
    )
    
    func main() {
    	ctx := context.WithValue(context.Background(), "trace_id", 12345678999999)
    	ctx = context.WithValue(ctx, "session", "asdfjladjf2222")
    	process(ctx)
    	ctx = context.WithValue(ctx, "trace_id", "asdfjladjf2222")
    	process(ctx)
    }
    
    func process(ctx context.Context) {
    	ret, ok := ctx.Value("trace_id").(int)
    	if !ok {
    		fmt.Println("获取ctx的trace_id失败")
    		ret2, ok2 := ctx.Value("trace_id").(string)
    		fmt.Println("获取ctx的trace_id失败",ret2,ok2)
    		return
    	}
    	fmt.Println("获取ctx的trace_id:", ret)
    
    	s, _ := ctx.Value("session").(string)
    	fmt.Println("获取ctx的session:", s)
    }
    

    输出:

    获取ctx的trace_id: 12345678999999
    获取ctx的session: asdfjladjf2222
    获取ctx的trace_id失败
    获取ctx的trace_id失败 asdfjladjf2222 true
    
    
  • 相关阅读:
    2019-2020-1 20175316 《信息安全系统设计基础》第5周学习总结
    2019-2020-1 20175316 《信息安全系统设计基础》第4周学习总结
    2019-2020-1 20175316 《信息安全系统设计基础》第3周学习总结
    第06组 Alpha冲刺(4/6)
    第06组 Alpha冲刺(3/6)
    第06组 Alpha冲刺(2/6)
    第06组 Alpha冲刺(1/6)
    第06组 团队Git现场编程实战
    团队项目-需求分析报告
    团队项目-选题报告
  • 原文地址:https://www.cnblogs.com/heris/p/16222727.html
Copyright © 2020-2023  润新知