go-study/err_group/weather.go
2023-12-28 17:46:49 +08:00

81 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package err_group
import (
"context"
"golang.org/x/sync/errgroup"
"math/rand"
"time"
)
type WeatherData struct {
City string
Weather string
Temp int
}
var WeatherList = []string{"晴", "阴", "多云", "小雨", "大雨"}
// fetchWeatherData 获取天气数据
func fetchWeatherData(ctx context.Context, city string) (*WeatherData, error) {
done := make(chan struct{}, 1) // 用于指示数据获取成功完成
data := new(WeatherData)
// 启动一个goroutine来获取天气数据
go func() {
// 这里仅为示例实际中这里会是API调用
// 为了模拟可能出现的超时或错误情况,这里随机地休眠一段时间
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
data.City = city
// 随机天气
data.Weather = WeatherList[rand.Intn(len(WeatherList))]
// 随机温度
data.Temp = rand.Intn(40)
done <- struct{}{}
}()
select {
case <-ctx.Done():
// 如果上下文被取消,返回错误
return nil, ctx.Err()
case <-done:
// 如果数据获取成功完成,返回数据
return data, nil
}
}
func GetAllCityWeatherData(timeOut time.Duration) ([]*WeatherData, error) {
// 创建一个携带cancel的context
ctx, cancel := context.WithTimeout(context.Background(), timeOut)
defer cancel() // 确保所有路径都调用cancel
// 初始化一个ErrGroup对象
g, ctx := errgroup.WithContext(ctx)
// 城市列表
cities := []string{"New York", "Tokyo", "Berlin", "Paris", "Beijing"}
list := make([]*WeatherData, 0, len(cities))
// 循环启动goroutine来获取每个城市的天气数据
for _, city := range cities {
city := city
g.Go(func() error {
// FetchWeatherData使用了上下文如果上下文被取消它应该立刻尝试返回
data, err := fetchWeatherData(ctx, city)
if err != nil {
return err
}
// 如果没有错误,将数据添加到列表中
list = append(list, data)
return nil
})
}
// 等待所有goroutine完成或出现错误
if err := g.Wait(); err != nil {
return nil, err
}
return list, nil
}