英文:
No Json returned
问题
我正在尝试使用Go协程将Json数据返回给请求。当我在不使用"go"的情况下测试test1(w, r)时,我的代码可以正常工作。但是当我将test1()作为一个协程使用时,我没有收到任何json数据。为什么会发生这种情况?
func main() {
http.HandleFunc("/test", viewdata)
http.ListenAndServe(":8080", nil)
}
func viewdata(w http.ResponseWriter, r *http.Request) {
go test1(w, r)
}
func test1(w http.ResponseWriter, r *http.Request) {
// 示例结构体
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
json, _ := json.Marshal(ll)
w.Write(json)
}
问题可能出在你的代码中使用了协程。在Go中,协程是轻量级的线程,它们在后台运行并且不会阻塞主线程。当你使用go test1(w, r)
将test1()
函数作为协程运行时,主线程会继续执行后续代码,而不会等待协程完成。
这可能导致在viewdata()
函数返回之前,协程test1()
还没有完成,因此没有任何json数据返回。你可以尝试在viewdata()
函数中使用等待组(sync.WaitGroup
)来等待协程完成,然后再返回数据给请求。
以下是修改后的代码示例:
import "sync"
func main() {
http.HandleFunc("/test", viewdata)
http.ListenAndServe(":8080", nil)
}
func viewdata(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
wg.Add(1)
go test1(w, r, &wg)
wg.Wait()
}
func test1(w http.ResponseWriter, r *http.Request, wg *sync.WaitGroup) {
defer wg.Done()
// 示例结构体
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
json, _ := json.Marshal(ll)
w.Write(json)
}
在修改后的代码中,我们使用了sync.WaitGroup
来等待协程完成。在viewdata()
函数中,我们创建了一个sync.WaitGroup
实例,并在协程开始前调用wg.Add(1)
来增加等待组的计数。然后,在test1()
函数中,我们使用defer wg.Done()
来在函数执行结束时通知等待组,表示协程已完成。最后,在viewdata()
函数中调用wg.Wait()
来等待所有协程完成后再返回数据给请求。
这样修改后,你应该能够正确地从协程中返回json数据给请求了。
英文:
I am trying to use a Go routine to return back Json data to a request. When I test1(w,r) without the "go" my code works. When I use test1() as a go routine I dont get any json data back. Why is this happening?
func main() {
http.HandleFunc("/test", viewdata)
http.ListenAndServe(":8080", nil)
}
func viewdata(w http.ResponseWriter, r *http.Request) {
go test1(w, r)
}
func test1(w http.ResponseWriter, r *http.Request) {
// example struct
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
json, _ := json.Marshal(ll)
w.Write(json)
}
答案1
得分: 1
根据你的代码流程,我没有看到使用goroutine的必要性。你可能有一些原因。
让我们来回答你的问题。目前,你的请求在viewdata
处理程序启动的goroutine之前就已经完成了。因此,你需要使用sync.WaitGroup
来等待goroutine test1
执行完毕。
你的更新代码如下:
func viewdata(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
wg.Add(1)
go test1(w, r, &wg)
wg.Wait()
}
func test1(w http.ResponseWriter, r *http.Request, wg *sync.WaitGroup) {
defer wg.Done()
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
json, _ := json.Marshal(ll)
w.Write(json)
}
英文:
As per your code flow, I do not see a point of using goroutine. May you have some reason.
Let's get to your question. Currently your request gets completed before the goroutine that was started by viewdata
handler. So, you have to use sync.WaitGroup
to wait for goroutine test1
to complete the execution.
Your update code:
func viewdata(w http.ResponseWriter, r *http.Request) {
var wg sync.WaitGroup
wg.Add(1)
go test1(w, r, &wg)
wg.Wait()
}
func test1(w http.ResponseWriter, r *http.Request, wg *sync.WaitGroup) {
defer wg.Done()
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
json, _ := json.Marshal(ll)
w.Write(json)
}
答案2
得分: 0
http处理程序已经作为goroutine生成了。所以你不需要再生成你自己的goroutine。
func viewdata(w http.ResponseWriter, r *http.Request) {
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
w.NewEncoder(w).Encode(ll)
}
英文:
http handler is already spawned as goroutine. So you don't need to spawn your goroutine.
func viewdata(w http.ResponseWriter, r *http.Request) {
ll := sample{
"city",
12,
}
w.Header().Set("Content-Type", "application/json")
w.NewEncoder(w).Encode(ll)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论