[{"data":1,"prerenderedAt":1619},["ShallowReactive",2],{"content:\u002F2025\u002F08\u002Fgo-timer":3,"surround:\u002F2025\u002F08\u002Fgo-timer":1610},{"id":4,"title":5,"body":6,"categories":1587,"date":1589,"description":1590,"draft":1591,"extension":1592,"image":1593,"meta":1594,"navigation":107,"path":1596,"permalink":1593,"published":1593,"readingTime":1597,"recommend":1593,"references":1593,"seo":1602,"sitemap":1603,"stem":1604,"tags":1605,"type":1608,"updated":1589,"__hash__":1609},"content\u002Fposts\u002F2025\u002F08\u002Fgo-timer.md","Go Timer 与 Ticker 定时器详解",{"type":7,"value":8,"toc":1578},"minimark",[9,14,18,28,32,265,271,274,279,282,380,383,391,394,397,409,412,415,418,612,615,621,625,631,634,744,747,928,931,955,958,961,965,968,1021,1024,1146,1150,1153,1201,1204,1571,1574],[10,11,13],"h2",{"id":12},"timer-定时器","timer 定时器",[15,16,17],"p",{},"golang 的 time 包内置了 timer 定时器，它包含了两种数据结构，分别是 Timer 和 Ticker",[19,20,21,25],"ol",{},[22,23,24],"li",{},"Timer，在未来的某一个时刻执行一次【一次性定时器】",[22,26,27],{},"Ticker，周期性的执行多次，需要手动触发停止【周期性定时器】",[10,29,31],{"id":30},"timer-的数据结构","timer 的数据结构",[33,34,39],"pre",{"className":35,"code":36,"language":37,"meta":38,"style":38},"language-go shiki shiki-themes github-light github-dark","type Timer struct {\n\tC         \u003C-chan Time\n\tinitTimer bool\n}\n\nfunc NewTimer(d Duration) *Timer {\n\tc := make(chan Time, 1)\n\tt := (*Timer)(newTimer(when(d), 0, sendTime, c, syncTimer(c)))\n\tt.C = c\n\treturn t\n}\n","go","",[40,41,42,66,85,96,102,109,143,176,235,249,260],"code",{"__ignoreMap":38},[43,44,47,51,55,58,62],"span",{"class":45,"data-line":46,"line":46},"line",1,[43,48,50],{"class":49},"szBVR","type",[43,52,54],{"class":53},"sScJk"," Timer",[43,56,57],{"class":49}," struct",[43,59,61],{"class":60},"sVt8B"," ",[43,63,65],{"class":64},"sSDpw","{\n",[43,67,69,73,76,79,82],{"class":45,"data-line":68,"line":68},2,[43,70,72],{"class":71},"indent","\t",[43,74,75],{"class":60},"C         ",[43,77,78],{"class":49},"\u003C",[43,80,81],{"class":49},"-chan",[43,83,84],{"class":53}," Time\n",[43,86,88,90,93],{"class":45,"data-line":87,"line":87},3,[43,89,72],{"class":71},[43,91,92],{"class":60},"initTimer ",[43,94,95],{"class":49},"bool\n",[43,97,99],{"class":45,"data-line":98,"line":98},4,[43,100,101],{"class":64},"}\n",[43,103,105],{"class":45,"data-line":104,"line":104},5,[43,106,108],{"emptyLinePlaceholder":107},true,"\n",[43,110,112,115,118,121,125,128,131,133,136,139,141],{"class":45,"data-line":111,"line":111},6,[43,113,114],{"class":49},"func",[43,116,117],{"class":53}," NewTimer",[43,119,120],{"class":64},"(",[43,122,124],{"class":123},"s4XuR","d",[43,126,127],{"class":53}," Duration",[43,129,130],{"class":64},")",[43,132,61],{"class":60},[43,134,135],{"class":49},"*",[43,137,138],{"class":53},"Timer",[43,140,61],{"class":60},[43,142,65],{"class":64},[43,144,146,148,151,154,157,160,163,166,169,173],{"class":45,"data-line":145,"line":145},7,[43,147,72],{"class":71},[43,149,150],{"class":60},"c ",[43,152,153],{"class":49},":=",[43,155,156],{"class":53}," make",[43,158,120],{"class":159},"sJX2D",[43,161,162],{"class":49},"chan",[43,164,165],{"class":53}," Time",[43,167,168],{"class":60},", ",[43,170,172],{"class":171},"sj4cs","1",[43,174,175],{"class":159},")\n",[43,177,179,181,184,186,188,190,192,194,196,198,201,204,207,209,211,213,215,218,221,224,226,229,231,233],{"class":45,"data-line":178,"line":178},8,[43,180,72],{"class":71},[43,182,183],{"class":60},"t ",[43,185,153],{"class":49},[43,187,61],{"class":60},[43,189,120],{"class":159},[43,191,135],{"class":49},[43,193,138],{"class":53},[43,195,130],{"class":159},[43,197,120],{"class":159},[43,199,200],{"class":53},"newTimer",[43,202,120],{"class":203},"sqkie",[43,205,206],{"class":53},"when",[43,208,120],{"class":64},[43,210,124],{"class":60},[43,212,130],{"class":64},[43,214,168],{"class":60},[43,216,217],{"class":171},"0",[43,219,220],{"class":60},", sendTime, c, ",[43,222,223],{"class":53},"syncTimer",[43,225,120],{"class":64},[43,227,228],{"class":60},"c",[43,230,130],{"class":64},[43,232,130],{"class":203},[43,234,175],{"class":159},[43,236,238,240,243,246],{"class":45,"data-line":237,"line":237},9,[43,239,72],{"class":71},[43,241,242],{"class":60},"t.C ",[43,244,245],{"class":49},"=",[43,247,248],{"class":60}," c\n",[43,250,252,254,257],{"class":45,"data-line":251,"line":251},10,[43,253,72],{"class":71},[43,255,256],{"class":49},"return",[43,258,259],{"class":60}," t\n",[43,261,263],{"class":45,"data-line":262,"line":262},11,[43,264,101],{"class":64},[15,266,267,268],{},"我们可以使用 NewTimer 去初始化一个定时器",[40,269,270],{"code":270},"func NewTimer(d Duration) *Timer",[15,272,273],{},"Timer 结构里有一个 Time 类型的管道 C，主要用于事件通知。在未到达设定时间的时候，管道内没有数据写入，一直处于阻塞状态，到达设定时间后，会向管道内写入一个系统时间，触发事件。",[275,276,278],"h3",{"id":277},"创建-timer","创建 Timer",[15,280,281],{},"代码示例：",[33,283,285],{"className":35,"code":284,"language":37,"meta":38,"style":38},"func main() {\n\tt := time.NewTimer(2 * time.Second)\n\tfmt.Println(\"\u003C-t.C\", \u003C-t.C)\n\n\tfmt.Println(\"2s结束了\")\n}\n",[40,286,287,302,329,357,361,376],{"__ignoreMap":38},[43,288,289,291,294,296,298,300],{"class":45,"data-line":46,"line":46},[43,290,114],{"class":49},[43,292,293],{"class":53}," main",[43,295,120],{"class":64},[43,297,130],{"class":64},[43,299,61],{"class":60},[43,301,65],{"class":64},[43,303,304,306,308,310,313,316,318,321,324,327],{"class":45,"data-line":68,"line":68},[43,305,72],{"class":71},[43,307,183],{"class":60},[43,309,153],{"class":49},[43,311,312],{"class":60}," time.",[43,314,315],{"class":53},"NewTimer",[43,317,120],{"class":159},[43,319,320],{"class":171},"2",[43,322,323],{"class":49}," *",[43,325,326],{"class":60}," time.Second",[43,328,175],{"class":159},[43,330,331,333,336,339,341,345,347,349,352,355],{"class":45,"data-line":87,"line":87},[43,332,72],{"class":71},[43,334,335],{"class":60},"fmt.",[43,337,338],{"class":53},"Println",[43,340,120],{"class":159},[43,342,344],{"class":343},"sZZnC","\"\u003C-t.C\"",[43,346,168],{"class":60},[43,348,78],{"class":49},[43,350,351],{"class":49},"-",[43,353,354],{"class":60},"t.C",[43,356,175],{"class":159},[43,358,359],{"class":45,"data-line":98,"line":98},[43,360,108],{"emptyLinePlaceholder":107},[43,362,363,365,367,369,371,374],{"class":45,"data-line":104,"line":104},[43,364,72],{"class":71},[43,366,335],{"class":60},[43,368,338],{"class":53},[43,370,120],{"class":159},[43,372,373],{"class":343},"\"2s结束了\"",[43,375,175],{"class":159},[43,377,378],{"class":45,"data-line":111,"line":111},[43,379,101],{"class":64},[15,381,382],{},"输出结果：",[33,384,389],{"className":385,"code":387,"language":388,"meta":38},[386],"language-text","\u003C-t.C 2025-08-20 18:43:43.768511304 +0800 CST m=+2.000062088\n2s结束了\n","text",[40,390,387],{"__ignoreMap":38},[15,392,393],{},"可以看到输出了结束之后的时间类型",[15,395,396],{},"timer 有两个常用的方法：",[19,398,399,404],{},[22,400,401],{},[40,402,403],{"code":403},"func (t *Timer) Reset(d Duration) bool",[22,405,406],{},[40,407,408],{"code":408},"func (t *Timer) Stop() bool",[15,410,411],{},"Reset 用于重置定时器的时间，哪怕已经定时器已经过时了",[15,413,414],{},"Stop 用于暂停，返回值表示是否正处于计时状态",[15,416,417],{},"示例代码：",[33,419,421],{"className":35,"code":420,"language":37,"meta":38,"style":38},"func main() {\n\tt := time.NewTimer(2 * time.Second)\n\tres := t.Stop()\n\tfmt.Println(\"是否处于计时状态\", res)\n\n\t\u002F\u002F 因为停止计时了，重置一下计时时间\n\tt.Reset(1 * time.Second)\n\tfmt.Println(\"\u003C-t.C\", \u003C-t.C)\n\n\tfmt.Println(\"1s结束了\")\n\n\tres = t.Stop()\n\tfmt.Println(\"是否处于计时状态\", res)\n}\n",[40,422,423,437,459,478,496,500,508,528,550,554,569,573,590,607],{"__ignoreMap":38},[43,424,425,427,429,431,433,435],{"class":45,"data-line":46,"line":46},[43,426,114],{"class":49},[43,428,293],{"class":53},[43,430,120],{"class":64},[43,432,130],{"class":64},[43,434,61],{"class":60},[43,436,65],{"class":64},[43,438,439,441,443,445,447,449,451,453,455,457],{"class":45,"data-line":68,"line":68},[43,440,72],{"class":71},[43,442,183],{"class":60},[43,444,153],{"class":49},[43,446,312],{"class":60},[43,448,315],{"class":53},[43,450,120],{"class":159},[43,452,320],{"class":171},[43,454,323],{"class":49},[43,456,326],{"class":60},[43,458,175],{"class":159},[43,460,461,463,466,468,471,474,476],{"class":45,"data-line":87,"line":87},[43,462,72],{"class":71},[43,464,465],{"class":60},"res ",[43,467,153],{"class":49},[43,469,470],{"class":60}," t.",[43,472,473],{"class":53},"Stop",[43,475,120],{"class":159},[43,477,175],{"class":159},[43,479,480,482,484,486,488,491,494],{"class":45,"data-line":98,"line":98},[43,481,72],{"class":71},[43,483,335],{"class":60},[43,485,338],{"class":53},[43,487,120],{"class":159},[43,489,490],{"class":343},"\"是否处于计时状态\"",[43,492,493],{"class":60},", res",[43,495,175],{"class":159},[43,497,498],{"class":45,"data-line":104,"line":104},[43,499,108],{"emptyLinePlaceholder":107},[43,501,502,504],{"class":45,"data-line":111,"line":111},[43,503,72],{"class":71},[43,505,507],{"class":506},"sJ8bj","\u002F\u002F 因为停止计时了，重置一下计时时间\n",[43,509,510,512,515,518,520,522,524,526],{"class":45,"data-line":145,"line":145},[43,511,72],{"class":71},[43,513,514],{"class":60},"t.",[43,516,517],{"class":53},"Reset",[43,519,120],{"class":159},[43,521,172],{"class":171},[43,523,323],{"class":49},[43,525,326],{"class":60},[43,527,175],{"class":159},[43,529,530,532,534,536,538,540,542,544,546,548],{"class":45,"data-line":178,"line":178},[43,531,72],{"class":71},[43,533,335],{"class":60},[43,535,338],{"class":53},[43,537,120],{"class":159},[43,539,344],{"class":343},[43,541,168],{"class":60},[43,543,78],{"class":49},[43,545,351],{"class":49},[43,547,354],{"class":60},[43,549,175],{"class":159},[43,551,552],{"class":45,"data-line":237,"line":237},[43,553,108],{"emptyLinePlaceholder":107},[43,555,556,558,560,562,564,567],{"class":45,"data-line":251,"line":251},[43,557,72],{"class":71},[43,559,335],{"class":60},[43,561,338],{"class":53},[43,563,120],{"class":159},[43,565,566],{"class":343},"\"1s结束了\"",[43,568,175],{"class":159},[43,570,571],{"class":45,"data-line":262,"line":262},[43,572,108],{"emptyLinePlaceholder":107},[43,574,576,578,580,582,584,586,588],{"class":45,"data-line":575,"line":575},12,[43,577,72],{"class":71},[43,579,465],{"class":60},[43,581,245],{"class":49},[43,583,470],{"class":60},[43,585,473],{"class":53},[43,587,120],{"class":159},[43,589,175],{"class":159},[43,591,593,595,597,599,601,603,605],{"class":45,"data-line":592,"line":592},13,[43,594,72],{"class":71},[43,596,335],{"class":60},[43,598,338],{"class":53},[43,600,120],{"class":159},[43,602,490],{"class":343},[43,604,493],{"class":60},[43,606,175],{"class":159},[43,608,610],{"class":45,"data-line":609,"line":609},14,[43,611,101],{"class":64},[15,613,614],{},"运行结果：",[33,616,619],{"className":617,"code":618,"language":388,"meta":38},[386],"是否处于计时状态 true\n\u003C-t.C 2025-08-20 19:00:29.577803872 +0800 CST m=+1.000104217\n1s结束了\n是否处于计时状态 false\n",[40,620,618],{"__ignoreMap":38},[10,622,624],{"id":623},"timeafterfunc","time.AfterFunc",[15,626,627,628],{},"来看一下函数定义\n",[40,629,630],{"code":630},"func AfterFunc(d Duration, f func()) *Timer",[15,632,633],{},"经过一段时间之后，调用回调函数并返回 timer\n注意点开源码发现，其 C【通道会被置 nil】",[33,635,637],{"className":35,"code":636,"language":37,"meta":38,"style":38},"\u002F\u002F AfterFunc waits for the duration to elapse and then calls f\n\u002F\u002F in its own goroutine. It returns a [Timer] that can\n\u002F\u002F be used to cancel the call using its Stop method.\n\u002F\u002F The returned Timer's C field is not used and will be nil.\nfunc AfterFunc(d Duration, f func()) *Timer {\n\treturn (*Timer)(newTimer(when(d), 0, goFunc, f, nil))\n}\n",[40,638,639,644,649,654,659,696,740],{"__ignoreMap":38},[43,640,641],{"class":45,"data-line":46,"line":46},[43,642,643],{"class":506},"\u002F\u002F AfterFunc waits for the duration to elapse and then calls f\n",[43,645,646],{"class":45,"data-line":68,"line":68},[43,647,648],{"class":506},"\u002F\u002F in its own goroutine. It returns a [Timer] that can\n",[43,650,651],{"class":45,"data-line":87,"line":87},[43,652,653],{"class":506},"\u002F\u002F be used to cancel the call using its Stop method.\n",[43,655,656],{"class":45,"data-line":98,"line":98},[43,657,658],{"class":506},"\u002F\u002F The returned Timer's C field is not used and will be nil.\n",[43,660,661,663,666,668,670,672,674,677,680,682,684,686,688,690,692,694],{"class":45,"data-line":104,"line":104},[43,662,114],{"class":49},[43,664,665],{"class":53}," AfterFunc",[43,667,120],{"class":64},[43,669,124],{"class":123},[43,671,127],{"class":53},[43,673,168],{"class":60},[43,675,676],{"class":123},"f",[43,678,679],{"class":49}," func",[43,681,120],{"class":159},[43,683,130],{"class":159},[43,685,130],{"class":64},[43,687,61],{"class":60},[43,689,135],{"class":49},[43,691,138],{"class":53},[43,693,61],{"class":60},[43,695,65],{"class":64},[43,697,698,700,702,704,706,708,710,712,714,716,718,720,722,724,726,728,730,733,736,738],{"class":45,"data-line":111,"line":111},[43,699,72],{"class":71},[43,701,256],{"class":49},[43,703,61],{"class":60},[43,705,120],{"class":159},[43,707,135],{"class":49},[43,709,138],{"class":53},[43,711,130],{"class":159},[43,713,120],{"class":159},[43,715,200],{"class":53},[43,717,120],{"class":203},[43,719,206],{"class":53},[43,721,120],{"class":64},[43,723,124],{"class":60},[43,725,130],{"class":64},[43,727,168],{"class":60},[43,729,217],{"class":171},[43,731,732],{"class":60},", goFunc, f, ",[43,734,735],{"class":171},"nil",[43,737,130],{"class":203},[43,739,175],{"class":159},[43,741,742],{"class":45,"data-line":145,"line":145},[43,743,101],{"class":64},[15,745,746],{},"示例代码",[33,748,750],{"className":35,"code":749,"language":37,"meta":38,"style":38},"func TestAfterFunc() {\n\tt := time.AfterFunc(1*time.Second, func() {\n\t\tfmt.Println(\"time.AfterFunc在1秒后被触发了\")\n\t})\n\n\tfmt.Println(\"\u003C-t.C\", \u003C-t.C)\n}\n\nfunc TestAfter() {\n\tch := time.After(1 * time.Second)\n\tfmt.Println(\"\u003Cch\", \u003C-ch)\n}\n",[40,751,752,767,799,816,827,831,853,857,861,876,900,924],{"__ignoreMap":38},[43,753,754,756,759,761,763,765],{"class":45,"data-line":46,"line":46},[43,755,114],{"class":49},[43,757,758],{"class":53}," TestAfterFunc",[43,760,120],{"class":64},[43,762,130],{"class":64},[43,764,61],{"class":60},[43,766,65],{"class":64},[43,768,769,771,773,775,777,780,782,784,786,789,791,793,795,797],{"class":45,"data-line":68,"line":68},[43,770,72],{"class":71},[43,772,183],{"class":60},[43,774,153],{"class":49},[43,776,312],{"class":60},[43,778,779],{"class":53},"AfterFunc",[43,781,120],{"class":159},[43,783,172],{"class":171},[43,785,135],{"class":49},[43,787,788],{"class":60},"time.Second, ",[43,790,114],{"class":49},[43,792,120],{"class":203},[43,794,130],{"class":203},[43,796,61],{"class":60},[43,798,65],{"class":203},[43,800,801,803,805,807,809,811,814],{"class":45,"data-line":87,"line":87},[43,802,72],{"class":71},[43,804,72],{"class":71},[43,806,335],{"class":60},[43,808,338],{"class":53},[43,810,120],{"class":64},[43,812,813],{"class":343},"\"time.AfterFunc在1秒后被触发了\"",[43,815,175],{"class":64},[43,817,818,820,822,825],{"class":45,"data-line":98,"line":98},[43,819,72],{"class":71},[43,821,38],{"class":60},[43,823,824],{"class":203},"}",[43,826,175],{"class":159},[43,828,829],{"class":45,"data-line":104,"line":104},[43,830,108],{"emptyLinePlaceholder":107},[43,832,833,835,837,839,841,843,845,847,849,851],{"class":45,"data-line":111,"line":111},[43,834,72],{"class":71},[43,836,335],{"class":60},[43,838,338],{"class":53},[43,840,120],{"class":159},[43,842,344],{"class":343},[43,844,168],{"class":60},[43,846,78],{"class":49},[43,848,351],{"class":49},[43,850,354],{"class":60},[43,852,175],{"class":159},[43,854,855],{"class":45,"data-line":145,"line":145},[43,856,101],{"class":64},[43,858,859],{"class":45,"data-line":178,"line":178},[43,860,108],{"emptyLinePlaceholder":107},[43,862,863,865,868,870,872,874],{"class":45,"data-line":237,"line":237},[43,864,114],{"class":49},[43,866,867],{"class":53}," TestAfter",[43,869,120],{"class":64},[43,871,130],{"class":64},[43,873,61],{"class":60},[43,875,65],{"class":64},[43,877,878,880,883,885,887,890,892,894,896,898],{"class":45,"data-line":251,"line":251},[43,879,72],{"class":71},[43,881,882],{"class":60},"ch ",[43,884,153],{"class":49},[43,886,312],{"class":60},[43,888,889],{"class":53},"After",[43,891,120],{"class":159},[43,893,172],{"class":171},[43,895,323],{"class":49},[43,897,326],{"class":60},[43,899,175],{"class":159},[43,901,902,904,906,908,910,913,915,917,919,922],{"class":45,"data-line":262,"line":262},[43,903,72],{"class":71},[43,905,335],{"class":60},[43,907,338],{"class":53},[43,909,120],{"class":159},[43,911,912],{"class":343},"\"\u003Cch\"",[43,914,168],{"class":60},[43,916,78],{"class":49},[43,918,351],{"class":49},[43,920,921],{"class":60},"ch",[43,923,175],{"class":159},[43,925,926],{"class":45,"data-line":575,"line":575},[43,927,101],{"class":64},[15,929,930],{},"输出结果",[33,932,936],{"className":933,"code":934,"language":935,"meta":38,"style":38},"language-bash shiki shiki-themes github-light github-dark","\u003Cch 2025-08-21 11:14:21.935064037 +0800 CST m=+2.001546026\ntime.AfterFunc在1秒后被触发了\n","bash",[40,937,938,950],{"__ignoreMap":38},[43,939,940,942,945,947],{"class":45,"data-line":46,"line":46},[43,941,78],{"class":49},[43,943,944],{"class":60},"ch 2025-08-21 11:14:21.935064037 +0800 CST m",[43,946,245],{"class":49},[43,948,949],{"class":343},"+2.001546026\n",[43,951,952],{"class":45,"data-line":68,"line":68},[43,953,954],{"class":60},"time.AfterFunc在1秒后被触发了\n",[15,956,957],{},"可以看到 t.C 一直为 nil，所以对应的子 goroutine 就会一直阻塞，无法输出",[15,959,960],{},"它存在的唯一作用是可以通过调用 Stop() 来取消定时器。而不能像正常 timer 一样通过 C 去等待信号的结束",[10,962,964],{"id":963},"timeafter","time.After",[15,966,967],{},"点开源码",[33,969,971],{"className":35,"code":970,"language":37,"meta":38,"style":38},"func After(d Duration) \u003C-chan Time {\n\treturn NewTimer(d).C\n}\n",[40,972,973,1000,1017],{"__ignoreMap":38},[43,974,975,977,980,982,984,986,988,990,992,994,996,998],{"class":45,"data-line":46,"line":46},[43,976,114],{"class":49},[43,978,979],{"class":53}," After",[43,981,120],{"class":64},[43,983,124],{"class":123},[43,985,127],{"class":53},[43,987,130],{"class":64},[43,989,61],{"class":60},[43,991,78],{"class":49},[43,993,81],{"class":49},[43,995,165],{"class":53},[43,997,61],{"class":60},[43,999,65],{"class":64},[43,1001,1002,1004,1006,1008,1010,1012,1014],{"class":45,"data-line":68,"line":68},[43,1003,72],{"class":71},[43,1005,256],{"class":49},[43,1007,117],{"class":53},[43,1009,120],{"class":159},[43,1011,124],{"class":60},[43,1013,130],{"class":159},[43,1015,1016],{"class":60},".C\n",[43,1018,1019],{"class":45,"data-line":87,"line":87},[43,1020,101],{"class":64},[15,1022,1023],{},"可以看到这个是个定时器，如果到时间就会往管道发送到时时间，相当于信号，通常配合 select case 使用",[33,1025,1027],{"className":35,"code":1026,"language":37,"meta":38,"style":38},"select {\n   case val := \u003C-ch:\n      fmt.Printf(\"val is %s\\n\", val)\n   case \u003C-time.After(time.Second * 2):\n      fmt.Println(\"timeout!!!\")\n   }\n",[40,1028,1029,1038,1060,1089,1121,1138],{"__ignoreMap":38},[43,1030,1031,1034,1036],{"class":45,"data-line":46,"line":46},[43,1032,1033],{"class":49},"select",[43,1035,61],{"class":60},[43,1037,65],{"class":64},[43,1039,1040,1043,1046,1049,1051,1053,1055,1057],{"class":45,"data-line":68,"line":68},[43,1041,1042],{"class":71},"   ",[43,1044,1045],{"class":49},"case",[43,1047,1048],{"class":60}," val ",[43,1050,153],{"class":49},[43,1052,61],{"class":49},[43,1054,78],{"class":49},[43,1056,351],{"class":49},[43,1058,1059],{"class":60},"ch:\n",[43,1061,1062,1065,1068,1070,1073,1075,1078,1081,1084,1087],{"class":45,"data-line":87,"line":87},[43,1063,1064],{"class":71},"    ",[43,1066,1067],{"class":71},"  ",[43,1069,335],{"class":60},[43,1071,1072],{"class":53},"Printf",[43,1074,120],{"class":159},[43,1076,1077],{"class":343},"\"val is ",[43,1079,1080],{"class":171},"%s\\n",[43,1082,1083],{"class":343},"\"",[43,1085,1086],{"class":60},", val",[43,1088,175],{"class":159},[43,1090,1091,1093,1095,1097,1099,1101,1104,1106,1108,1111,1113,1116,1118],{"class":45,"data-line":98,"line":98},[43,1092,1042],{"class":71},[43,1094,1045],{"class":49},[43,1096,61],{"class":49},[43,1098,78],{"class":49},[43,1100,351],{"class":49},[43,1102,1103],{"class":60},"time.",[43,1105,889],{"class":53},[43,1107,120],{"class":159},[43,1109,1110],{"class":60},"time.Second ",[43,1112,135],{"class":49},[43,1114,1115],{"class":171}," 2",[43,1117,130],{"class":159},[43,1119,1120],{"class":60},":\n",[43,1122,1123,1125,1127,1129,1131,1133,1136],{"class":45,"data-line":104,"line":104},[43,1124,1064],{"class":71},[43,1126,1067],{"class":71},[43,1128,335],{"class":60},[43,1130,338],{"class":53},[43,1132,120],{"class":159},[43,1134,1135],{"class":343},"\"timeout!!!\"",[43,1137,175],{"class":159},[43,1139,1140,1142,1144],{"class":45,"data-line":111,"line":111},[43,1141,1042],{"class":71},[43,1143,38],{"class":60},[43,1145,101],{"class":64},[10,1147,1149],{"id":1148},"ticker","Ticker",[15,1151,1152],{},"和 Timer 是类似的",[33,1154,1156],{"className":35,"code":1155,"language":37,"meta":38,"style":38},"type Ticker struct {\n   C \u003C-chan Time \u002F\u002F The channel on which the ticks are delivered.\n   r runtimeTimer\n}\n",[40,1157,1158,1171,1187,1197],{"__ignoreMap":38},[43,1159,1160,1162,1165,1167,1169],{"class":45,"data-line":46,"line":46},[43,1161,50],{"class":49},[43,1163,1164],{"class":53}," Ticker",[43,1166,57],{"class":49},[43,1168,61],{"class":60},[43,1170,65],{"class":64},[43,1172,1173,1175,1178,1180,1182,1184],{"class":45,"data-line":68,"line":68},[43,1174,1042],{"class":71},[43,1176,1177],{"class":60},"C ",[43,1179,78],{"class":49},[43,1181,81],{"class":49},[43,1183,165],{"class":53},[43,1185,1186],{"class":506}," \u002F\u002F The channel on which the ticks are delivered.\n",[43,1188,1189,1191,1194],{"class":45,"data-line":87,"line":87},[43,1190,1042],{"class":71},[43,1192,1193],{"class":60},"r ",[43,1195,1196],{"class":53},"runtimeTimer\n",[43,1198,1199],{"class":45,"data-line":98,"line":98},[43,1200,101],{"class":64},[15,1202,1203],{},"不过 Ticker 是周期性，Timer 是一次性的",[33,1205,1207],{"className":35,"code":1206,"language":37,"meta":38,"style":38},"func TestTicker(sem \u003C-chan struct{}) {\n\tt := time.NewTicker(1 * time.Second)\n\tdefer t.Stop()\n\tfor {\n\t\tselect {\n\t\tcase \u003C-t.C:\n\t\t\tfmt.Println(\"轮询\")\n\t\tcase \u003C-sem:\n\t\t\tfmt.Println(\"结束Ticker\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc main() {\n\t\u002F\u002F 创建一个退出信号，要退出时往里面写值\n\tsem := make(chan struct{}, 1)\n\tgo TestTicker(sem)\n\t\u002F\u002F 5s后退出轮询\n\ttime.AfterFunc(5*time.Second, func() {\n\t\tsem \u003C- struct{}{}\n\t})\n\tfor {\n\t}\n}\n",[40,1208,1209,1240,1263,1278,1289,1301,1318,1337,1354,1373,1384,1394,1402,1406,1410,1425,1433,1461,1476,1484,1512,1535,1546,1557,1566],{"__ignoreMap":38},[43,1210,1211,1213,1216,1218,1221,1223,1225,1227,1229,1232,1234,1236,1238],{"class":45,"data-line":46,"line":46},[43,1212,114],{"class":49},[43,1214,1215],{"class":53}," TestTicker",[43,1217,120],{"class":64},[43,1219,1220],{"class":123},"sem",[43,1222,61],{"class":49},[43,1224,78],{"class":49},[43,1226,81],{"class":49},[43,1228,57],{"class":49},[43,1230,1231],{"class":159},"{",[43,1233,824],{"class":159},[43,1235,130],{"class":64},[43,1237,61],{"class":60},[43,1239,65],{"class":64},[43,1241,1242,1244,1246,1248,1250,1253,1255,1257,1259,1261],{"class":45,"data-line":68,"line":68},[43,1243,72],{"class":71},[43,1245,183],{"class":60},[43,1247,153],{"class":49},[43,1249,312],{"class":60},[43,1251,1252],{"class":53},"NewTicker",[43,1254,120],{"class":159},[43,1256,172],{"class":171},[43,1258,323],{"class":49},[43,1260,326],{"class":60},[43,1262,175],{"class":159},[43,1264,1265,1267,1270,1272,1274,1276],{"class":45,"data-line":87,"line":87},[43,1266,72],{"class":71},[43,1268,1269],{"class":49},"defer",[43,1271,470],{"class":60},[43,1273,473],{"class":53},[43,1275,120],{"class":159},[43,1277,175],{"class":159},[43,1279,1280,1282,1285,1287],{"class":45,"data-line":98,"line":98},[43,1281,72],{"class":71},[43,1283,1284],{"class":49},"for",[43,1286,61],{"class":60},[43,1288,65],{"class":159},[43,1290,1291,1293,1295,1297,1299],{"class":45,"data-line":104,"line":104},[43,1292,72],{"class":71},[43,1294,72],{"class":71},[43,1296,1033],{"class":49},[43,1298,61],{"class":60},[43,1300,65],{"class":203},[43,1302,1303,1305,1307,1309,1311,1313,1315],{"class":45,"data-line":111,"line":111},[43,1304,72],{"class":71},[43,1306,72],{"class":71},[43,1308,1045],{"class":49},[43,1310,61],{"class":49},[43,1312,78],{"class":49},[43,1314,351],{"class":49},[43,1316,1317],{"class":60},"t.C:\n",[43,1319,1320,1322,1324,1326,1328,1330,1332,1335],{"class":45,"data-line":145,"line":145},[43,1321,72],{"class":71},[43,1323,72],{"class":71},[43,1325,72],{"class":71},[43,1327,335],{"class":60},[43,1329,338],{"class":53},[43,1331,120],{"class":64},[43,1333,1334],{"class":343},"\"轮询\"",[43,1336,175],{"class":64},[43,1338,1339,1341,1343,1345,1347,1349,1351],{"class":45,"data-line":178,"line":178},[43,1340,72],{"class":71},[43,1342,72],{"class":71},[43,1344,1045],{"class":49},[43,1346,61],{"class":49},[43,1348,78],{"class":49},[43,1350,351],{"class":49},[43,1352,1353],{"class":60},"sem:\n",[43,1355,1356,1358,1360,1362,1364,1366,1368,1371],{"class":45,"data-line":237,"line":237},[43,1357,72],{"class":71},[43,1359,72],{"class":71},[43,1361,72],{"class":71},[43,1363,335],{"class":60},[43,1365,338],{"class":53},[43,1367,120],{"class":64},[43,1369,1370],{"class":343},"\"结束Ticker\"",[43,1372,175],{"class":64},[43,1374,1375,1377,1379,1381],{"class":45,"data-line":251,"line":251},[43,1376,72],{"class":71},[43,1378,72],{"class":71},[43,1380,72],{"class":71},[43,1382,1383],{"class":49},"return\n",[43,1385,1386,1388,1390,1392],{"class":45,"data-line":262,"line":262},[43,1387,72],{"class":71},[43,1389,72],{"class":71},[43,1391,38],{"class":60},[43,1393,101],{"class":203},[43,1395,1396,1398,1400],{"class":45,"data-line":575,"line":575},[43,1397,72],{"class":71},[43,1399,38],{"class":60},[43,1401,101],{"class":159},[43,1403,1404],{"class":45,"data-line":592,"line":592},[43,1405,101],{"class":64},[43,1407,1408],{"class":45,"data-line":609,"line":609},[43,1409,108],{"emptyLinePlaceholder":107},[43,1411,1413,1415,1417,1419,1421,1423],{"class":45,"data-line":1412,"line":1412},15,[43,1414,114],{"class":49},[43,1416,293],{"class":53},[43,1418,120],{"class":64},[43,1420,130],{"class":64},[43,1422,61],{"class":60},[43,1424,65],{"class":64},[43,1426,1428,1430],{"class":45,"data-line":1427,"line":1427},16,[43,1429,72],{"class":71},[43,1431,1432],{"class":506},"\u002F\u002F 创建一个退出信号，要退出时往里面写值\n",[43,1434,1436,1438,1441,1443,1445,1447,1449,1451,1453,1455,1457,1459],{"class":45,"data-line":1435,"line":1435},17,[43,1437,72],{"class":71},[43,1439,1440],{"class":60},"sem ",[43,1442,153],{"class":49},[43,1444,156],{"class":53},[43,1446,120],{"class":159},[43,1448,162],{"class":49},[43,1450,57],{"class":49},[43,1452,1231],{"class":203},[43,1454,824],{"class":203},[43,1456,168],{"class":60},[43,1458,172],{"class":171},[43,1460,175],{"class":159},[43,1462,1464,1466,1468,1470,1472,1474],{"class":45,"data-line":1463,"line":1463},18,[43,1465,72],{"class":71},[43,1467,37],{"class":49},[43,1469,1215],{"class":53},[43,1471,120],{"class":159},[43,1473,1220],{"class":60},[43,1475,175],{"class":159},[43,1477,1479,1481],{"class":45,"data-line":1478,"line":1478},19,[43,1480,72],{"class":71},[43,1482,1483],{"class":506},"\u002F\u002F 5s后退出轮询\n",[43,1485,1487,1489,1491,1493,1495,1498,1500,1502,1504,1506,1508,1510],{"class":45,"data-line":1486,"line":1486},20,[43,1488,72],{"class":71},[43,1490,1103],{"class":60},[43,1492,779],{"class":53},[43,1494,120],{"class":159},[43,1496,1497],{"class":171},"5",[43,1499,135],{"class":49},[43,1501,788],{"class":60},[43,1503,114],{"class":49},[43,1505,120],{"class":203},[43,1507,130],{"class":203},[43,1509,61],{"class":60},[43,1511,65],{"class":203},[43,1513,1515,1517,1519,1521,1523,1525,1527,1529,1531,1533],{"class":45,"data-line":1514,"line":1514},21,[43,1516,72],{"class":71},[43,1518,72],{"class":71},[43,1520,1440],{"class":60},[43,1522,78],{"class":49},[43,1524,351],{"class":49},[43,1526,57],{"class":49},[43,1528,1231],{"class":64},[43,1530,824],{"class":64},[43,1532,1231],{"class":64},[43,1534,101],{"class":64},[43,1536,1538,1540,1542,1544],{"class":45,"data-line":1537,"line":1537},22,[43,1539,72],{"class":71},[43,1541,38],{"class":60},[43,1543,824],{"class":203},[43,1545,175],{"class":159},[43,1547,1549,1551,1553,1555],{"class":45,"data-line":1548,"line":1548},23,[43,1550,72],{"class":71},[43,1552,1284],{"class":49},[43,1554,61],{"class":60},[43,1556,65],{"class":159},[43,1558,1560,1562,1564],{"class":45,"data-line":1559,"line":1559},24,[43,1561,72],{"class":71},[43,1563,38],{"class":60},[43,1565,101],{"class":159},[43,1567,1569],{"class":45,"data-line":1568,"line":1568},25,[43,1570,101],{"class":64},[15,1572,1573],{},"Go 的 break 与很多语言有点不同。在 C、Java、Python 这种语言里，break 默认退出最近的一层循环，而 Go 里也一样——但这里的“最近一层循环”要注意，select 语句本身被视作一层语法块，所以 break 默认只会跳出 select，不会跳出包含它的 for。所以直接return退出函数。",[1575,1576,1577],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sSDpw, html code.shiki .sSDpw{--shiki-default:#005cc5;--shiki-dark:#79b8ff}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJX2D, html code.shiki .sJX2D{--shiki-default:#e36209;--shiki-dark:#ffab70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sqkie, html code.shiki .sqkie{--shiki-default:#5a32a3;--shiki-dark:#b392f0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":38,"searchDepth":98,"depth":98,"links":1579},[1580,1581,1584,1585,1586],{"id":12,"depth":68,"text":13},{"id":30,"depth":68,"text":31,"children":1582},[1583],{"id":277,"depth":87,"text":278},{"id":623,"depth":68,"text":624},{"id":963,"depth":68,"text":964},{"id":1148,"depth":68,"text":1149},[1588],"Go语言","2025-08-21","Timer 用于一次性计时，可通过 C 通道接收时间；AfterFunc 用于异步回调，不通过 C 通道；Ticker 用于周期性计时；select 多个就绪 case 随机选择，break 仅退出当前块",false,"md",null,{"slots":1595},{},"\u002F2025\u002F08\u002Fgo-timer",{"text":1598,"minutes":1599,"time":1600,"words":1601},"5 min read",4.51,270600,902,{"title":5,"description":1590},{"loc":1596},"posts\u002F2025\u002F08\u002Fgo-timer",[1606,1607],"context","goroutine","tech","5ax7Q9yC1HOLcXNWjF2_IsN1FkTd6ipL8Y8RTPocbFY",[1611,1615],{"title":1612,"path":1613,"stem":1614,"date":1589,"type":1608,"children":-1},"Go 反射机制详解","\u002F2025\u002F08\u002Fgo-reflect","posts\u002F2025\u002F08\u002Fgo-reflect",{"title":1616,"path":1617,"stem":1618,"date":1589,"type":1608,"children":-1},"Minikube 安装与环境配置","\u002F2025\u002F08\u002Fminikube-install","posts\u002F2025\u002F08\u002Fminikube-install",1786555056314]