Skip to content

Instantly share code, notes, and snippets.

@nicewook
Created August 10, 2020 02:23
Show Gist options
  • Save nicewook/9c63ba747fdac1d88e40613e5f1f7862 to your computer and use it in GitHub Desktop.
Save nicewook/9c63ba747fdac1d88e40613e5f1f7862 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"time"
)
func main() {
doneOrDone := make(chan interface{})
doneRepeat := make(chan interface{})
doneMain := make(chan interface{})
go func() {
time.Sleep(time.Second * 2)
close(doneOrDone)
}()
repeat := func(done <-chan interface{}, values ...interface{}) <-chan interface{} {
valueStream := make(chan interface{})
go func() {
defer func() {
close(valueStream)
fmt.Println("closed")
}()
for {
time.Sleep(time.Millisecond * 100)
for _, v := range values {
select {
case <-done:
return
case valueStream <- v:
}
}
}
}()
return valueStream
}
orDone := func(done <-chan interface{}, c <-chan interface{}) <-chan interface{} {
valStream := make(chan interface{})
go func() {
defer func() {
close(valStream)
close(doneMain)
}()
for {
select {
case <-done:
fmt.Println("done. first")
return
case v, ok := <-c:
if ok == false {
fmt.Println("channel closed")
return
}
select {
case valStream <- v:
fmt.Println("valStream")
case <-done:
fmt.Println("done. second")
}
}
}
}()
return valStream
}
generater := repeat(doneRepeat, []interface{}{1, 2, 3, 4, 5})
var i int
for v := range orDone(done, generater) {
i++
if i > 2 {
break
}
fmt.Printf("i: %d, value: %v\n", i, v)
}
<-doneMain
fmt.Println("Done")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment