You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Goroutine未向Channel写入数据问题求助

问题分析与修复

你的代码存在几个关键问题,导致通道无法正确接收PDF数据:

1. 变量遮蔽导致包调用错误

goroutine中的代码pdf, err := pdf.GenerateFromHTML(...)存在变量遮蔽问题:左边声明的pdf局部变量覆盖了同名的pdf包(假设pdf是你导入的PDF生成包),导致实际调用的是未初始化的变量方法而非包函数。这会引发逻辑错误,即使你认为获取到了PDF值,也可能是错误的结果。

2. goroutine内的错误无法传递到主流程

goroutine中使用:=声明的err是局部变量,主函数中的if err != nil检查的是base64.DecodeString的错误,完全无法感知GenerateFromHTML的执行错误。如果GenerateFromHTML实际返回错误,goroutine不会往通道发送数据,主goroutine接收已关闭的通道会得到零值(空切片),最终返回空PDF。

修复后的代码

func (h *Handler) GeneratePdfFromHTML(c echo.Context) (err error) {
    req := &createPdfFromHTMLRequest{}
    if err := req.bind(c); err != nil {
        return c.JSON(http.StatusBadRequest, utils.NewError(err))
    }

    rawDecodedText, err := base64.StdEncoding.DecodeString(req.HTML)
    if err != nil {
        return c.JSON(http.StatusInternalServerError, utils.NewError(err))
    }

    // 定义结构体传递数据和错误
    type pdfResult struct {
        data []byte
        err  error
    }
    buf := make(chan pdfResult)

    go func() {
        defer close(buf)
        // 重命名变量,避免遮蔽包名
        pdfData, err := pdf.GenerateFromHTML(string(rawDecodedText))
        // 无论成功失败,都往通道传递结果
        buf <- pdfResult{data: pdfData, err: err}
    }()

    // 接收goroutine的执行结果
    res := <-buf
    if res.err != nil {
        return c.JSON(http.StatusInternalServerError, utils.NewError(res.err))
    }

    return c.Blob(http.StatusOK, MIMEApplicationPdf, res.data)
}

额外说明

  • 通过自定义结构体pdfResult,可以同时传递PDF数据和错误,确保主流程能感知goroutine内的执行状态。
  • 重命名goroutine内的变量为pdfData,彻底避免包名与变量名冲突的问题。
  • 移除了主函数中多余的if err != nil检查,该检查的是之前DecodeString的错误,已经在前面的分支处理完毕。

内容的提问来源于stack exchange,提问作者Aníbal Deboni Neto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:44:59