這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
package mainimport ( "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 ./wrappertestage donename donesex done{10 test false}real 0m3.011suser 0m0.001ssys 0m0.005s
當前業務中,其中一個使用者請求,需要查詢多次nosql,為了不串列等待,做了一個非同步wrap封裝,每個查詢都自己啟動一個go程來進行。
當然,有其它並行網路/io請求需要的也都可以這麼做,這裡使用了interface的變參,具體的實現函數和調用者,都需要明白每個參數的類型。