如果有任何频道关闭,有没有办法打破选择?

时间:2017-11-09 10:24:35

标签: go

假设我们正在选择两个频道。运行几次后,其中一个通道关闭。我如何突破选择?

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)
    closed := make(chan bool, 1)
    go func() {
        for i := 0; i < 5; i++ {
            ch <- 1
        }
        close(ch)
    }()

    for {
        select {
        case v := <-ch:
            fmt.Printf("v is %v\n", v)
        case <-closed:
            fmt.Println("The server is closed!")
            return
        }
    }
    fmt.Println("Break!")
}

无限地封锁。如何使它工作?

2 个答案:

答案 0 :(得分:3)

如果频道说它没有更多项目,您可以返回:

OneSignal.push(["getUserId", function(playerId) {
//console.log("OneSignal User ID:", playerId);
if(playerId){
     var url    = SITEURL;
                    $.ajax({
                    url:url,
                    type:'post',
                    async:true,
                    data:{ playerId : playerId, isAjax : 'Yes' },
                    success:function(data){
                    //console.log("OneSignal User ID:", playerId);                      
                    }
});
}

答案 1 :(得分:1)

以下是工作代码:

  1. 更改了select-case的顺序。 (根据@zzn的评论,这种行为是随机的,最好不要依赖于此 - 更好地检查频道是否已关闭)。
  2. 写入closed频道
  3. https://play.golang.org/p/K83XcPbr7b

    package main
    import (
        "fmt"
    )
    
    func main() {
        ch := make(chan int)
        closed := make(chan bool)
        go func() {
            for i := 0; i < 5; i++ {
                ch <- i
            }
            close(ch)
        closed <- true
        }()
    
        for {
            select {
            case <- closed:
                fmt.Println("The server is closed!")
                return
            case v := <- ch:
                fmt.Printf("v is %v\n", v)
            }
        }
        fmt.Println("Break!")
    }
    

    如果你不改变案件的顺序,就会有额外的&#34;零&#34;价值:https://play.golang.org/p/JJaomKgqy8

    检查频道是否已关闭可能会更好吗?

    https://play.golang.org/p/7Nd63b3JZ_

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        ch := make(chan int)
        go func() {
            for i := 0; i < 5; i++ {
                ch <- i
            }
            close(ch)
        }()
    
        for {
            select {
            case v, hasMore := <- ch:
            if !hasMore {
                return
            }
                fmt.Printf("v is %v\n", v)
            }
        }
        fmt.Println("Break!")
    }