checkSuccess()如果任務完成,我有一個回傳 true 的函式。
我想checkSuccess()每 1 秒呼叫一次并中斷,直到它回傳true或超時。
我現在擁有的是使用 goroutine 來運行一個 for 回圈,我checkSuccess()每 1 秒呼叫一次。在主流程中,我time.After用來檢查整個檢查持續時間是否已超時。
func myfunc (timeout time.Duration) {
successChan := make(chan struct{})
timeoutChan := make(chan struct{})
// Keep listening to the task.
go func() {
for {
select {
// Exit the forloop if the timeout has been reached
case <-timeoutChan:
return
default:
}
// Early exit if task has succeed.
if checkSuccess() {
close(successChan)
return
}
time.Sleep(time.Second)
}
}()
// Once timeout, stop listening to the task.
select {
case <-time.After(timeout):
close(timeoutChan)
return
case <-successChan:
return
}
return
}
它實際上已經實作了我的目標,但我發現它非常乏味。有沒有更好(更短)的方法來寫它?
uj5u.com熱心網友回復:
您不需要單獨的 goroutine 或通道:
func myfunc (timeout time.Duration) {
ticker:=time.NewTicker(time.Second)
defer ticker.Close()
to:=time.NewTimer(timeout)
defer to.Stop()
for {
select {
case <-to.C:
return // timeout
case <-ticker:
if checkSuccess() {
return
}
}
}
}
uj5u.com熱心網友回復:
我更喜歡context.Context在這樣的情況下使用,以便實用功能可以更輕松地適應各種現實世界場景。
我還會回傳一些東西,error例如 fromctx.Err()或 the bool,以向呼叫者提供一些反饋(呼叫者可能會決定丟棄它):
func tryFunc(ctx context.Context, f func() bool) bool {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return false
case <-ticker.C:
if b := f(); b {
return b
}
}
}
}
游樂場:https ://go.dev/play/p/Iz_urEkBMIi
PS:確保背景關系有超時。context.Background()沒有
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/417937.html
標籤:
