使用以下代码:
package main
import (
"github.com/davecgh/go-spew/spew"
"sync"
"time"
)
func callbackWithTimeout(cbFunc func() ([]byte, error), timeout time.Duration) {
defer wg.Done() //I don't want this function to know about sync.WaitGroup
time.Sleep(timeout)
d, e := cbFunc()
spew.Dump(d)
spew.Dump(e)
}
var wg sync.WaitGroup
func main() {
wg.Add(1)
go func() {
cbFunc := func() ([]byte, error) {
//I feel like I should be able to defer here instead
return nil, nil
}
callbackWithTimeout(cbFunc, time.Duration(4*time.Second))
}()
println("some line")
wg.Wait()
}
在函数 callbackWithTimeout
中,我不想使用 defer wg.Done()
因为这不是 callbackWithTimeout()
的问题到 wg.Done()
。我该如何着手实现这样的事情?即,删除 callbackWithTimeout
中的任何 sync.WaitGroup
?我在理解关注点分离方面有点问题,因为回调函数不必知道 WaitGroup ,但在这种情况下,我似乎别无选择?
我觉得这应该是调用者的责任 wg.Done()
(在本例中是 cbFunc
)但是缺乏任何关于如何在 Go 中实现它的文档或想法的简明引用,因为根据定义,回调函数所做的就是回调函数。那么,我哪里做错了?
愚蠢的假设是您在重构过程中真正做出的。下面的工作代码。非常感谢。
package main
import (
"errors"
"github.com/davecgh/go-spew/spew"
"sync"
"time"
)
func callbackWithTimeout(cbFunc func() ([]byte, error), timeout time.Duration) {
time.Sleep(timeout)
d, e := cbFunc()
spew.Dump(d)
spew.Dump(e)
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
callbackWithTimeout(func() ([]byte, error) {
b := []byte{1, 2, 3, 4}
e := errors.New("error123")
return b, e
}, time.Duration(2*time.Second))
}()
println("some line")
wg.Wait()
}
最佳答案
可能是这样的?
package main
import (
"sync"
"time"
"github.com/davecgh/go-spew/spew"
)
func callbackWithTimeout(cbFunc func() ([]byte, error), timeout time.Duration) {
time.Sleep(timeout)
d, e := cbFunc()
spew.Dump(d)
spew.Dump(e)
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done() // move it here
cbFunc := func() ([]byte, error) {
//I feel like I should be able to defer here instead
return nil, nil
}
callbackWithTimeout(cbFunc, time.Duration(4*time.Second))
}()
println("some line")
wg.Wait()
}
关于Goroutines、回调和 sync.WaitGroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45660762/