Golang中如何顺序执行HTTP.Get请求

Golang中如何顺序执行HTTP.Get请求 大家好,我搜索了很久但没找到这个问题的答案:HTTP请求是同步还是异步的?所有信息都表明它们是并发的,但我不理解在这个上下文中这意味着什么。让我举个例子:假设我有一堆结构体需要用两个不同HTTP调用的响应来填充,我需要的方式是(这是一个简化示例,我实际需要以这种方式执行):

type person struct {
    name string
    age  int
}
var ids interface{}
var names interface{}
idsToSearch := [1,2,3]
var personList [] interface {}
for _, i := range idsToSearch{
   resp, err = http.Get("webServiceWithId's", i)
   defer resp.Body.Close()
   dec := json.NewDecoder(r.Body)
   dec.Decode(&ids)   
   for _, item := range ids.id {
         var rPerson person
         person.id = item.id
         resp, err = http.Get("webServiceWithNames")
         defer resp.Body.Close()
         dec := json.NewDecoder(r.Body)
         dec.Decode(&names)
         for _, name := range names.id {
             person.name = name.name
        }
        personList.append(personList, person)
   }
}

不知道我说得是否清楚,我想问的是:我能否在循环中串联两个(或更多)请求,让第二个请求使用第一个请求的响应,并且程序会等待第二个请求完成后再继续执行循环并发起新的第一类请求?


更多关于Golang中如何顺序执行HTTP.Get请求的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

是的。调用 Get 方法会暂停该 goroutine 的执行,直到返回结果后才会继续执行。

更多关于Golang中如何顺序执行HTTP.Get请求的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,HTTP请求默认是同步执行的,这意味着当你调用http.Get()时,程序会阻塞直到收到响应或发生错误。你提供的代码示例已经实现了顺序执行:第二个请求会等待第一个请求完成,因为它们在同一个循环迭代中顺序调用。

以下是修正后的示例代码,展示了如何正确实现这种顺序执行模式:

package main

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

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

type IDResponse struct {
    IDs []struct {
        ID int `json:"id"`
    } `json:"ids"`
}

type NameResponse struct {
    Names []struct {
        Name string `json:"name"`
    } `json:"names"`
}

func main() {
    idsToSearch := []int{1, 2, 3}
    var personList []Person

    for _, id := range idsToSearch {
        // 第一个HTTP请求 - 获取ID
        resp, err := http.Get(fmt.Sprintf("https://api.example.com/ids/%d", id))
        if err != nil {
            fmt.Printf("Error fetching IDs: %v\n", err)
            continue
        }

        var idResp IDResponse
        err = json.NewDecoder(resp.Body).Decode(&idResp)
        resp.Body.Close()
        if err != nil {
            fmt.Printf("Error decoding ID response: %v\n", err)
            continue
        }

        // 对每个ID执行第二个HTTP请求
        for _, item := range idResp.IDs {
            // 第二个HTTP请求 - 获取名称
            nameResp, err := http.Get(fmt.Sprintf("https://api.example.com/names/%d", item.ID))
            if err != nil {
                fmt.Printf("Error fetching names: %v\n", err)
                continue
            }

            var nameRespObj NameResponse
            err = json.NewDecoder(nameResp.Body).Decode(&nameRespObj)
            nameResp.Body.Close()
            if err != nil {
                fmt.Printf("Error decoding name response: %v\n", err)
                continue
            }

            // 创建人员对象
            if len(nameRespObj.Names) > 0 {
                person := Person{
                    Name: nameRespObj.Names[0].Name,
                    Age:  0, // 根据实际需求设置年龄
                }
                personList = append(personList, person)
            }
        }
    }

    fmt.Printf("Processed %d persons\n", len(personList))
}

关键点说明:

  1. 同步执行:每个http.Get()调用都会阻塞当前goroutine,直到请求完成
  2. 顺序保证:第二个请求在第一个请求解码完成后才执行
  3. 错误处理:添加了适当的错误处理,避免程序崩溃
  4. 资源清理:正确关闭响应体,避免资源泄漏

这种模式确保了:

  • 第一个请求完成后才开始第二个请求
  • 当前迭代的所有请求完成后才进入下一个迭代
  • 程序会等待每个请求完成后再继续执行

如果你需要提高性能,可以考虑使用goroutine并发执行独立的请求序列,但对于依赖前一个请求结果的场景,这种顺序执行是正确的方法。

回到顶部