我有一个从数据库返回Json的方法,它可以正常工作,但是当我尝试使它并发时,它不会返回任何内容并且不会给出任何错误。例如,这是方法正常工作
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
db,err := sql.Open("DB_Connect")
if err != nil {
log.Fatal(err)
println(err)
}
var result string
errr := db.QueryRow("select json_build_object('Expiration', array_to_json(array_agg(t))) from (select fullname,ad_end from profiles where id=32)t").Scan(&result)
defer db.Close()
switch {
case errr != nil:
log.Fatal(errr)
}
fmt.Fprintf(w,result)
}
上面的方法正常工作,数据返回到浏览器,然后我尝试将此方法设为异步
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
go func(){
db,err := sql.Open("DB_Connect")
if err != nil {
log.Fatal(err)
println(err)
}
var result string
errr := db.QueryRow("select json_build_object('Expiration', array_to_json(array_agg(t))) from (select fullname,ad_end from profiles where id=32)t").Scan(&result)
defer db.Close()
switch {
case errr != nil:
log.Fatal(errr)
}
fmt.Fprintf(w,result)
}()
}
上面的异步没有返回任何我唯一改变的是我在方法中添加了 Go func(),以便它是异步的,其他一切都是相同的。我检查了数据库并返回相同的内容,只是不知道为什么async没有将结果打印回浏览器。
答案 0 :(得分:3)
net / http服务器在处理程序返回时完成响应。在处理程序返回后写入响应的任何内容都将被忽略。
处理程序函数Listing_Expiration
在匿名函数执行fmt.Fprintf(w,result)
之前返回。
要解决此问题,请使用sync.WaitGroup:
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
wg.Add(1)
go func(){
defer wg.Done()
// same code here as in question
}()
wg.Wait()
}
net / http服务器为每个连接启动goroutine并在这些goroutine中运行处理程序。如果问题中的代码是完整的处理程序,那么就没有理由再启动另一个goroutine。