context

作者: 个00个 | 来源:发表于2019-04-12 10:19 被阅读0次
    1. 为啥需要context, 可以参考这个文章

    https://www.flysnow.org/2017/05/12/go-in-action-go-context.html

    package main
    
    import (
        "fmt"
        "context"
        "time"
    )
    
    func main() {
        // context.Background 返回一个空 Context -- 根节点。。
        ctx, cancel := context.WithCancel(context.Background())
        // context.WithCancel 创建了一个可取消的子 Context
    
        go func(ctx context.Context) {
            for {
                select {
    
                // 接受是否可取消的channel
                case <-ctx.Done():
                    fmt.Println("exit ...")
                    return
                default:
                    fmt.Println("going ...")
                    time.Sleep(2 * time.Second)
                }
            }
        }(ctx)
    
        time.Sleep(10 * time.Second)
        fmt.Println("notify ...")
    
        // 创建时返回的 cancel ... 直接执行即可取消。
        cancel()
    
        // 等待检查是否退出
        time.Sleep(5 * time.Second)
    }
    
    /**
        going ...
        going ...
        going ...
        going ...
        going ...
        notify ...
        exit ...
     */
    
    1. context包能干什么
    type Context interface {
            // 设置超时
        Deadline() (deadline time.Time, ok bool)
            // 用来确定是否取消了 
        Done() <-chan struct{}
            // 获取ctx的错误 可以是  超时 DeadlineExecced 也可以是 canceled
        Err() error
            // 绑定一些值. 
        Value(key interface{}) interface{}
    }
    

    内置的两个 emptyCtx, 即根Context

    • background
    • todo
    // 创建一个可以取消的
    func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
    // 创建一个有结束时间的  --  time.AfterFunc  到某个时间之后结束
    func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
    // 从当前开始经过多长时间之后结束
    func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
    // 绑定key value到Context中
    func WithValue(parent Context, key, val interface{}) Context 
    

    // 大概就是这些东西了呀

    1. 不要把Context放在结构体中,要以参数的方式传递
    2. 以Context作为参数的函数方法,应该把Context作为第一个参数,放在第一位。
    3. 给一个函数方法传递Context的时候,不要传递nil,如果不知道传递什么,就使用context.TODO
    4. Context的Value相关方法应该传递必须的数据,不要什么数据都使用这个传递
    5. Context是线程安全的,可以放心的在多个goroutine中传递
    

    这个文章说了context的坏话
    https://faiface.github.io/post/context-should-go-away-go2/

    相关文章

      网友评论

          本文标题:context

          本文链接:https://www.haomeiwen.com/subject/vrexwqtx.html