设为首页 加入收藏

TOP

golang中的errgroup(三)
2023-07-23 13:29:46 】 浏览:64
Tags:golang errgroup
} func CoursewareList() ([]Courseware, error) { time.Sleep(3 * time.Second) return []Courseware{ {Id: 1, Name: "课件1", Code: "CW1", CreateId: 1, CreateName: "", CoverId: 1, CoverPath: ""}, {Id: 2, Name: "课件2", Code: "CW2", CreateId: 2, CreateName: "", CoverId: 2, CoverPath: ""}, }, nil }

当然,errgroup中也有针对上下文的errgroup.WithContext函数,如果我们想控制请求接口的时间,用这个是最合适不过的。如果请求超时会返回一个关闭上下文的报错,像下面这样

package main

import (
	"context"
	"fmt"
	"golang.org/x/sync/errgroup"
	"time"
)

type Courseware struct {
	Id         int64
	Name       string
	Code       string
	CreateId   int64
	CreateName string
	CoverId    int64
	CoverPath  string
}

type User struct {
	Id   int64
	Name string
}

type File struct {
	Id   int64
	Path string
}

var coursewares []Courseware
var users map[int64]User
var files map[int64]File
var err error

func main() {
	// 查询课件
	...

	// 获取用户ID、文件ID
	...

  // 定义一个带超时时间的上下文,1秒钟超时
	ctx, cancelFunc := context.WithTimeout(context.Background(), 1*time.Second)
	defer cancelFunc()
  // 定义一个带上下文的errgroup,使用上面带有超时时间的上下文
	eg, ctx := errgroup.WithContext(ctx)
	// 此处放到协程里
	eg.Go(func() error {
		// 批量获取用户信息
		users, err = UserMap(ctx, userIds)
		if err != nil {
			fmt.Println("获取用户错误:", err)
			return err
		}
		return nil
	})

	// 此处放到协程里
	eg.Go(func() error {
		// 批量获取文件信息
		files, err = FileMap(ctx, fileIds)
		if err != nil {
			fmt.Println("获取文件错误:", err)
			return err
		}
		return nil
	})

	if goErr := eg.Wait(); goErr != nil {
		fmt.Println("goroutine err:", err)
		return
	}

	// 填充
	for i, courseware := range coursewares {
		if user, ok := users[courseware.CreateId]; ok {
			coursewares[i].CreateName = user.Name
		}

		if file, ok := files[courseware.CoverId]; ok {
			coursewares[i].CoverPath = file.Path
		}
	}
	fmt.Println(coursewares)
}

func UserMap(ctx context.Context, ids []int64) (map[int64]User, error) {
	result := make(chan map[int64]User)
	go func() {
		time.Sleep(2 * time.Second) // 假装请求超过1秒钟
		result <- map[int64]User{
			1: {Id: 1, Name: "liu"},
			2: {Id: 2, Name: "kang"},
		}
	}()

	select {
	case <-ctx.Done(): // 如果上下文结束直接返回错误信息
		return nil, ctx.Err()
	case res := <-result: // 返回正确结果
		return res, nil
	}
}

func FileMap(ctx context.Context, ids []int64) (map[int64]File, error) {
	return map[int64]File{
		1: {Id: 1, Path: "/a/b/c.jpg"},
		2: {Id: 2, Path: "/a/b/c/d.jpg"},
	}, nil
}

func CoursewareList() ([]Courseware, error) {
	time.Sleep(3 * time.Second)
	return []Courseware{
		{Id: 1, Name: "课件1", Code: "CW1", CreateId: 1, CreateName: "", CoverId: 1, CoverPath: ""},
		{Id: 2, Name: "课件2", Code: "CW2", CreateId: 2, CreateName: "", CoverId: 2, CoverPath: ""},
	}, nil
}

执行上面的代码:

go run waitgroup.go
获取用户错误: context deadline exceeded
goroutine err: context deadline exceeded
首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇golang中的nil接收器 下一篇golang中的字符串

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目