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

Go包开发:确保总页数仅被获取一次的实现需求

针对你开发Go HTTP客户端的需求,我整理了一个简洁且符合Go编程风格的实现方案,完美解决首次获取总页数并缓存的问题:

核心实现思路
  • 用结构体封装HTTP客户端、缓存的总页数、并发控制锁和已获取标记
  • 首次调用GetPage时,从响应中提取总页数并缓存到Client实例
  • Total方法直接返回缓存的总页数,同时保证并发安全
完整代码示例
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"sync"
)

// 替换为你的API实际返回的响应结构
type PageResponse struct {
	Data        []interface{} `json:"data"`
	TotalPages  int           `json:"total_pages"`
	CurrentPage int           `json:"current_page"`
}

type Client struct {
	httpClient *http.Client
	totalPages int
	mu         sync.RWMutex // 读写锁,优化并发场景下的性能
	fetched    bool         // 标记是否已获取过总页数
}

// NewClient 创建一个初始化好的Client实例
func NewClient() *Client {
	return &Client{
		httpClient: &http.Client{},
	}
}

// GetPage 获取指定页码的数据,首次调用时自动缓存总页数
func (c *Client) GetPage(page int) (*PageResponse, error) {
	// 替换为你的实际API地址
	url := fmt.Sprintf("https://your-service-url.com/api/pages?page=%d", page)
	resp, err := c.httpClient.Get(url)
	if err != nil {
		return nil, fmt.Errorf("failed to send request: %w", err)
	}
	defer resp.Body.Close()

	var pageResp PageResponse
	if err := json.NewDecoder(resp.Body).Decode(&pageResp); err != nil {
		return nil, fmt.Errorf("failed to parse response: %w", err)
	}

	// 仅在首次获取时更新总页数
	c.mu.Lock()
	defer c.mu.Unlock()
	if !c.fetched {
		c.totalPages = pageResp.TotalPages
		c.fetched = true
	}

	return &pageResp, nil
}

// Total 返回缓存的总页数,如果尚未获取过则返回0
func (c *Client) Total() int {
	c.mu.RLock()
	defer c.mu.RUnlock()
	return c.totalPages
}

// 可选:如果需要在未调用GetPage时返回明确错误,可修改Total方法如下
// func (c *Client) Total() (int, error) {
// 	c.mu.RLock()
// 	defer c.mu.RUnlock()
// 	if !c.fetched {
// 		return 0, fmt.Errorf("total pages not available yet - call GetPage first")
// 	}
// 	return c.totalPages, nil
// }
关键细节说明
  • 并发安全:使用sync.RWMutex而非普通sync.Mutex,因为Total是读操作,多个goroutine可以同时读取缓存值,只有当GetPage更新缓存时才会独占锁,性能更优。
  • 缓存逻辑:fetched标记确保只有第一次请求会更新总页数——如果你的服务总页数可能动态变化(比如数据实时更新),可以移除这个标记,每次请求都同步更新缓存的总页数。
  • HTTP连接复用:内置的http.Client会维护一个连接池,避免每次请求都新建TCP连接,大幅降低请求耗时,符合HTTP最佳实践。
  • 错误处理:用%w包装错误,保留原始错误链,方便上层调用方进行错误判断和处理。

内容的提问来源于stack exchange,提问作者Mikołaj Hołysz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:11:51