这是我的代码:
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"runtime"
"sync"
)
type Data struct {
Link string `json:"url"`
}
type Result struct {
Code uint32
Msg string `json:"msg"`
Data Data `json:"data"`
}
const (
URL = "http://qiye.wxsdc.ediankai.com/api/v1/suppliers/1/staff/1/box/get"
SIGNKEY = "i5OqMrNXVyOJ5GEMYoEtRHqN1P9ghk6I"
DATA_ID = "2965612126"
EQU_ID = "1482806063"
)
func getMD5Hash(text string) string {
hasher := md5.New()
hasher.Write([]byte(text))
return hex.EncodeToString(hasher.Sum(nil))
}
func getUrl(payload []byte, wg *sync.WaitGroup, result chan string) {
req, err := http.NewRequest("POST", URL, bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
var res Result
json.Unmarshal(body, &res)
log.Println(res.Data.Link)
result <- res.Data.Link
wg.Add(-1)
}
func main() {
parameterStr := fmt.Sprintf("%vdata_id%vequ_id%v%v", SIGNKEY, DATA_ID, EQU_ID, SIGNKEY)
log.Println(parameterStr)
sign := getMD5Hash(parameterStr)
log.Println(sign)
var payload map[string]string = make(map[string]string)
payload["equ_id"] = EQU_ID
payload["data_id"] = DATA_ID
payload["sign"] = sign
payloadJson, err := json.Marshal(payload)
if err != nil {
log.Fatalln("convet paylod failed!")
}
log.Println(string(payloadJson))
runtime.GOMAXPROCS(runtime.NumCPU())
var wg sync.WaitGroup
result := make(chan string)
for i := 0; i < 10; i++ {
wg.Add(1)
go getUrl(payloadJson, &wg, result)
}
wg.Wait()
for link := range result {
fmt.Println(link)
}
log.Println("Done!")
}
可是:
for link := range result {
fmt.Println(link)
}
log.Println("Done!")
无法执行,原因是什么?
答案 0 :(得分:1)
您需要关闭结果通道,以便从中读取的for循环在完成时中断。为此,您可以将最后一部分重写为:
var wg sync.WaitGroup
result := make(chan string)
go func() {
for link := range result {
fmt.Println(link)
}
}()
for i := 0; i < 10; i++ {
wg.Add(1)
go getUrl(payloadJson, &wg, result)
}
wg.Wait()
close(result)
答案 1 :(得分:0)
你的for循环永不停止。当所有getUrl
完成后,它会继续等待result
。试试这个:
wg.Wait()
close(result)
for link := range result {
fmt.Println(link)
}
log.Println("Done!")
如果要打印结果,可以这样做:
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"runtime"
"sync"
)
type Data struct {
Link string `json:"url"`
}
type Result struct {
Code uint32
Msg string `json:"msg"`
Data Data `json:"data"`
}
const (
URL = "http://qiye.wxsdc.ediankai.com/api/v1/suppliers/1/staff/1/box/get"
SIGNKEY = "i5OqMrNXVyOJ5GEMYoEtRHqN1P9ghk6I"
DATA_ID = "2965612126"
EQU_ID = "1482806063"
)
func getMD5Hash(text string) string {
hasher := md5.New()
hasher.Write([]byte(text))
return hex.EncodeToString(hasher.Sum(nil))
}
func getUrl(payload []byte, wg *sync.WaitGroup, result chan string) {
defer func(){
wg.Done()
}();
req, err := http.NewRequest("POST", URL, bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
var res Result
json.Unmarshal(body, &res)
log.Println(res.Data.Link)
result <- res.Data.Link
}
func monitor(wg *sync.WaitGroup, cs chan string) {
wg.Wait()
close(cs)
}
func printResult(result <-chan string, done chan<- bool) {
for i := range result {
fmt.Println(i)
}
done <- true
}
func main() {
parameterStr := fmt.Sprintf("%vdata_id%vequ_id%v%v", SIGNKEY, DATA_ID, EQU_ID, SIGNKEY)
log.Println(parameterStr)
sign := getMD5Hash(parameterStr)
log.Println(sign)
var payload map[string]string = make(map[string]string)
payload["equ_id"] = EQU_ID
payload["data_id"] = DATA_ID
payload["sign"] = sign
payloadJson, err := json.Marshal(payload)
if err != nil {
log.Fatalln("convet paylod failed!")
}
log.Println(string(payloadJson))
runtime.GOMAXPROCS(runtime.NumCPU())
var wg sync.WaitGroup
result := make(chan string)
for i := 0; i < 10; i++ {
wg.Add(1)
go getUrl(payloadJson, &wg, result)
}
go monitor(&wg, result)
done := make(chan bool, 1)
go printResult(result, done)
<-done
log.Println("Done!")
}