Golang中如何在API请求超过5秒后立即返回JSON结构

Golang中如何在API请求超过5秒后立即返回JSON结构 我有一个处理多个事务的 Go 函数,需要在 5 秒内发送响应。如何在函数执行期间持续检查,如果代码执行超过 5 秒就返回默认的 false 值。

11 回复

好的,明白了,你在关闭通道。谢谢兄弟!

更多关于Golang中如何在API请求超过5秒后立即返回JSON结构的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


看起来很有说服力,但能否请您举个例子?

确实如此,但如何处理同时到达的多个请求呢?

这听起来像是一个不同的问题。不如重新表述一个新问题?

是的,我想要实现的是:我有一个处理多个事务请求的函数。每个请求的响应应该在5秒内完成。

Sub和Tick两个函数是并行运行的对吧,那么通道是如何知道在条件为真后退出呢?

两个函数都会在通道上调用 close(done)。此后,它们都无法再向该通道写入数据。而使用 range 遍历通道的 main 函数会检测到通道已被关闭,并退出循环。

  • 打开一个通道,当函数完成时向该通道写入数据
  • 将函数作为 Goroutine 启动,并将通道传递给它
  • 在调用函数中,循环等待五秒钟以接收通道写入
  • 如果 Goroutine 向通道写入数据,则返回成功
  • 否则,返回失败

@lutzhorn 我有一个处理多个事务请求的函数,每个请求的响应应在5秒内完成

请看:

package main

import (
	"fmt"
	"time"
)

// Sub 函数需要一些时间完成,然后通过通道发送信号
func Sub(done chan<- bool) {
	time.Sleep(3 * time.Second)
	done <- true
	close(done)
}

// Tick 函数最多等待五秒。为了展示效果,每秒返回一次 `false`
func Tick(done chan<- bool) {
	for i := 5; i > 0; i-- {
		time.Sleep(time.Second)
		done <- false
	}
	close(done)
}

func main() {
	done := make(chan bool)

	// 在两个 Goroutine 中启动函数,将通道传递给两者
	go Sub(done)
	go Tick(done)

	// 监听通道。只要任一函数关闭了通道,我们就结束
	for b := range done {
		fmt.Printf("done: %v\n", b)
	}
}

https://play.golang.com/p/Y9vApBgEO5G

在Go语言中,您可以使用context包和select语句来实现API请求超时控制。以下是一个示例代码,演示如何在5秒后强制返回默认JSON响应:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

type Response struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
}

func main() {
	http.HandleFunc("/process", processHandler)
	http.ListenAndServe(":8080", nil)
}

func processHandler(w http.ResponseWriter, r *http.Request) {
	// 创建5秒超时的context
	ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
	defer cancel()

	// 创建通道用于接收处理结果
	resultChan := make(chan Response)

	// 在goroutine中执行耗时操作
	go func() {
		// 模拟耗时操作
		success := processTransactions()
		resultChan <- Response{Success: success, Message: "处理完成"}
	}()

	// 使用select监听多个通道
	select {
	case result := <-resultChan:
		// 正常完成,返回实际结果
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(result)
	case <-ctx.Done():
		// 超时或取消,返回默认false值
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(Response{
			Success: false,
			Message: "请求超时",
		})
	}
}

func processTransactions() bool {
	// 模拟耗时的事务处理
	// 这里可以是您的实际业务逻辑
	time.Sleep(6 * time.Second) // 测试用,实际会超时
	return true
}

另一个更简洁的版本,使用http.TimeoutHandler

package main

import (
	"encoding/json"
	"net/http"
	"time"
)

func main() {
	handler := http.TimeoutHandler(
		http.HandlerFunc(processHandler),
		5*time.Second,
		"请求处理超时",
	)
	
	http.Handle("/process", handler)
	http.ListenAndServe(":8080", nil)
}

func processHandler(w http.ResponseWriter, r *http.Request) {
	// 您的业务逻辑
	success := processTransactions()
	
	response := Response{
		Success: success,
		Message: "处理完成",
	}
	
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}

func processTransactions() bool {
	// 模拟耗时操作
	time.Sleep(6 * time.Second)
	return true
}

两种方法都能在5秒后自动返回{"success": false, "message": "请求超时"}的JSON响应。第一种方法提供更细粒度的控制,第二种方法更简洁易用。

回到顶部