英文:
Async function call in REST API
问题
这里有一个函数returnAllArticles
,它将被用于REST API的调用,该函数返回一组文章。在这个函数内部,调用了一个异步函数DoneAsync
。这个异步函数可能需要一些时间来处理自己的数据。我希望返回一个JSON值,即使异步函数还没有完成。我贴下了代码:
func returnAllArticles(w http.ResponseWriter, r *http.Request){
fmt.Println("Endpoint Hit: returnAllArticles")
json.NewEncoder(w).Encode(Articles)
val := DoneAsync()
fmt.Println("Done is running ...")
fmt.Println(<- val)
}
func DoneAsync() chan int {
r := make(chan int)
fmt.Println("Warming up ...")
go func() {
time.Sleep(3 * time.Second)
r <- 1
fmt.Println("Done ...")
}()
return r
}
func handleRequests() {
myRouter := mux.NewRouter().StrictSlash(true)
myRouter.HandleFunc("/articles", returnAllArticles)
log.Fatal(http.ListenAndServe(":8080", myRouter))
}
但是在我的情况下,直到异步函数完成后,JSON值才会返回。我无法获得异步函数的特性。
英文:
Here I have one function i.e returnAllArticles which will be called for REST API and this function returns a list of articles and inside this function one async function i.e DoneAsync is being called. This aysnc function may take some time to process its own data. I want json value i.e all articles should be returned whether that async function is complete or not. Code I have pasted below
func returnAllArticles(w http.ResponseWriter, r *http.Request){
fmt.Println("Endpoint Hit: returnAllArticles")
json.NewEncoder(w).Encode(Articles)
val := DoneAsync()
fmt.Println("Done is running ...")
fmt.Println(<- val)
}
func DoneAsync() chan int {
r := make(chan int)
fmt.Println("Warming up ...")
go func() {
time.Sleep(3 * time.Second)
r <- 1
fmt.Println("Done ...")
}()
return r
}
func handleRequests() {
myRouter := mux.NewRouter().StrictSlash(true)
myRouter.HandleFunc("/articles", returnAllArticles);
log.Fatal(http.ListenAndServe(":8080",myRouter))
}
But in my case json value is not returning until async func is done. I am not getting asynchronous features for that async function.
答案1
得分: 1
这行代码将会阻塞,直到有一个值被写入到 val
中:
fmt.Println(<-val)
所以你的 DoneAsync
函数创建了一个 goroutine 来处理某些事情,并最终将结果写入到 val
通道中,但是调用它的处理程序会等待直到有东西被写入到该通道中。
如果你希望在进行处理的同时发送编码结果,你可以检查响应处理程序是否实现了 Flusher
接口,并进行刷新:
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
英文:
This line will block until a value is written to val
:
fmt.Println(<- val)
So your DoneAsync
function creates a goroutine that goes on to process something, and in the end writes to the val
channel, but the handler that called it waits until something is written to that channel.
If you want the encoded result to be sent while you're doing this processing, you can when if the response handler implements Flusher
, and flush it:
if f, ok:=w.(http.Flusher); ok {
f.Flush()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论