package main import ( "fmt" "sync" "time" ) type WaitGroupWrapper struct { sync.WaitGroup } func (w *WaitGroupWrapper) Wrap(cb func(argvs ...interface{}), argvs ...interface{}) { w.Add(1) go func() { cb(argvs...) w.Done() }() } type MyStruct struct { Age int Name string Sex bool } func GetAge(argvs ...interface{}) { age := argvs[0].(int) my := argvs[1].(*MyStruct) my.Age = age time.Sleep(time.Second * 1) fmt.Println("age done") } func GetName(argvs ...interface{}) { name := argvs[0].(string) my := argvs[1].(*MyStruct) my.Name = name time.Sleep(time.Second * 2) fmt.Println("name done") } func GetSex(argvs ...interface{}) { my := argvs[0].(*MyStruct) my.Sex = false time.Sleep(time.Second * 3) fmt.Println("sex done") } func main() { var wg WaitGroupWrapper var my MyStruct wg.Wrap(GetAge, 10, &my) wg.Wrap(GetName, "test", &my) wg.Wrap(GetSex, &my) wg.Wait() fmt.Println(my) }
这段标红的代码,做的事情就对需要并行进行函数的一个封装,当所有的函数完成时,才会返回。
$time ./wrappertest age done name done sex done {10 test false} real 0m3.011s user 0m0.001s sys 0m0.005s
当前业务中,其中一个用户请求,需要查询多次nosql,为了不串行等待,做了一个异步的wrap封装,每个查询都自己启动一个go程来进行。
当然,有其它并行网络/io请求需要的也都可以这么做,这里使用了interface的变参,具体的实现函数和调用者,都需要明白每个参数的类型。
有疑问加站长微信联系(非本文作者)