Goroutines、回调和 sync.WaitGroup

标签 go callback goroutine

使用以下代码:

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/

相关文章:

go - "go test"和 "bazel test"中的不同文件权限错误

git - golang docker 私有(private) github 存储库

go - 如何修剪字符串的前导和尾随空格?

在单独的 goroutine 中显示进度的 HTTP 服务器

go - 一个通用的 http 处理程序而不是几个

node.js - 如何修复此错误 TypeError [ERR_INVALID_CALLBACK] : Callback must be a function

android - 绑定(bind)到正在运行的服务(在 finish() 之后)/回调处理程序

android接口(interface)使回调函数可选

go - Google Cloud Storage-同时列出对象(Go)

go - 发生错误时如何停止goroutine