代码
package main
import (
"fmt"
"sync"
)
func work2(inputValue interface{}, responseChannel chan interface{}) {
user, ok := inputValue.(User)
if !ok {
return
}
if user.Age == 2 {
responseChannel <- user
}
}
type CollectFunc func(interface{}, chan interface{})
// Collect 从切片中筛选可用数据
// @param limit 限制goroutine数量 (视情况而定 不要设置太大)
// @param f 执行函数
// @param inputArr 待筛选的数组/切片
// @return 返回的切片
func Collect(limit uint, f CollectFunc, filterData ...interface{}) []interface{} {
var result []interface{}
if len(filterData) == 0 {
return result
}
if limit == 0 {
return result
}
wg := &sync.WaitGroup{}
limiter := make(chan struct{}, limit)
defer close(limiter)
responseChannel := make(chan interface{}, 50)
wgResponse := &sync.WaitGroup{}
go func() {
wgResponse.Add(1)
for response := range responseChannel {
result = append(result, response)
}
wgResponse.Done()
}()
for _, inputValue := range filterData {
wg.Add(1)
limiter <- struct{}{}
go func(inputValue interface{}, response chan interface{}, limiter chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
f(inputValue, responseChannel)
<-limiter
}(inputValue, responseChannel, limiter, wg)
}
wg.Wait()
close(responseChannel)
wgResponse.Wait()
return result
}
type User struct {
Id int
Age int
}
func main() {
var users []interface{}
users = append(users, User{
Id: 1,
Age: 2,
})
users = append(users, User{
Id: 1,
Age: 2,
})
users = append(users, User{
Id: 1,
Age: 2,
})
users = append(users, User{
Id: 1,
Age: 2,
})
users = append(users, User{
Id: 1,
Age: 4,
})
users = append(users, User{
Id: 1,
Age: 3,
})
result := Collect(10, work2, users...)
fmt.Println(result)
}
参考
[1]:
http://docs.lvrui.io/2020/03/26/go%E8%AF%AD%E8%A8%80%E5%9C%A8goroutine%E4%B8%AD%E6%8B%BF%E5%88%B0%E8%BF%94%E5%9B%9E%E5%80%BC/