设计思路
- 扇出:使用多个goroutine并发地调用不同的天气API,每个goroutine负责一个API的请求和解析。
- 扇入:通过多个channel接收每个goroutine返回的数据,然后在一个goroutine中从这些channel中收集数据并进行合并处理。
核心代码
package main
import (
"fmt"
"sync"
)
// WeatherData 定义天气数据结构
type WeatherData struct {
Temperature float64
}
// FetchWeatherFromAPI1 模拟从API1获取天气数据
func FetchWeatherFromAPI1(resultChan chan<- WeatherData) {
// 实际这里是调用API1并解析数据
data := WeatherData{Temperature: 25.0}
resultChan <- data
close(resultChan)
}
// FetchWeatherFromAPI2 模拟从API2获取天气数据
func FetchWeatherFromAPI2(resultChan chan<- WeatherData) {
// 实际这里是调用API2并解析数据
data := WeatherData{Temperature: 23.0}
resultChan <- data
close(resultChan)
}
// FetchWeatherFromAPI3 模拟从API3获取天气数据
func FetchWeatherFromAPI3(resultChan chan<- WeatherData) {
// 实际这里是调用API3并解析数据
data := WeatherData{Temperature: 27.0}
resultChan <- data
close(resultChan)
}
// MergeWeatherData 合并天气数据
func MergeWeatherData(api1Chan, api2Chan, api3Chan <-chan WeatherData) WeatherData {
var wg sync.WaitGroup
wg.Add(3)
var totalTemp float64
var count int
go func() {
for data := range api1Chan {
totalTemp += data.Temperature
count++
}
wg.Done()
}()
go func() {
for data := range api2Chan {
totalTemp += data.Temperature
count++
}
wg.Done()
}()
go func() {
for data := range api3Chan {
totalTemp += data.Temperature
count++
}
wg.Done()
}()
go func() {
wg.Wait()
avgTemp := totalTemp / float64(count)
mergedData := WeatherData{Temperature: avgTemp}
fmt.Println("Merged Data:", mergedData)
}()
return WeatherData{}
}
func main() {
api1Chan := make(chan WeatherData)
api2Chan := make(chan WeatherData)
api3Chan := make(chan WeatherData)
go FetchWeatherFromAPI1(api1Chan)
go FetchWeatherFromAPI2(api2Chan)
go FetchWeatherFromAPI3(api3Chan)
MergeWeatherData(api1Chan, api2Chan, api3Chan)
}