1 回答

TA貢獻1860條經(jīng)驗 獲得超8個贊
該context
包提供了類似的功能。使用context.Context
一些 Go-esque 模式,您可以實現(xiàn)您所需要的。
因此,要實現(xiàn)此功能,您的函數(shù)應(yīng)該更像:
func walk(ctx context.Context, doc *html.Node, ch chan *html.Node) {
? ? var wg sync.WaitGroup
? ? defer close(ch)
? ? var f func(*html.Node)
? ? f = func(n *html.Node) {
? ? ? ? defer wg.Done()
? ? ? ? ch <- n
? ? ? ? for c := n.FirstChild; c != nil; c = c.NextSibling {
? ? ? ? ? ? select {
? ? ? ? ? ? case <-ctx.Done():
? ? ? ? ? ? ? ? return // quit the function as it is cancelled
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? wg.Add(1)
? ? ? ? ? ? ? ? go f(c)
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? select {
? ? case <-ctx.Done():
? ? ? ? return // perhaps it was cancelled so quickly
? ? default:
? ? ? ? wg.Add(1)
? ? ? ? go f(doc)
? ? ? ? wg.Wait()
? ? }
}
在調(diào)用該函數(shù)時,您將得到類似以下內(nèi)容的信息:
// ...
ctx, cancelFunc := context.WithCancel(context.Background())
walk(ctx, doc, ch)
for value := range ch {
? ? // ...
? ? if someCondition {
? ? ? ? cancelFunc()
? ? ? ? // the for loop will automatically exit as the channel is being closed for the inside
? ? }
}
- 1 回答
- 0 關(guān)注
- 142 瀏覽
添加回答
舉報