用go语言实现请求url的内容,当超过指定时间自动返回
package main
import (
"context"
"errors"
"fmt"
"io"
"net/http"
"time"
)
func main() {
content, err := getUrlContent("https://github.com/", 500*time.Millisecond)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(content)
}
//获取url的内容,并设定超时事件
func getUrlContent(url string, timeout time.Duration) (string, error) {
type Resp struct {
content string
err error
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)//超时控制context
defer cancel()//函数返回时调用cancel,避免内存泄露
ch := make(chan Resp,1)//子协程结束时将返回值放入该通道,通知当前协程子协程已结束
go func() {//开启子协程获取url内容
res, err := http.Get(url)
if err != nil {
ch <- Resp{"", err}
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)//读取内容
if err != nil {
ch <- Resp{"", err}
return
}
ch <- Resp{string(body), nil}
}()
//当前协程等待,监听通道可读事件
select {
case resp := <-ch://子协程结束事件
return resp.content, resp.err
case <-ctx.Done()://超时事件
return "", errors.New("超时了")
}
}