You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.0 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}