or-channel

介绍

or-channel模式是将若干个done channel合并成一个单一的channel,如果其中有一个channel完成工作,则将所有的channel退出

示例

package main

import "fmt"
import "time"

// 定义方法,因为or方法会有递归调用
var or func(...<-chan interface{}) <-chan interface{}

func main() {
	// 方法主体,将多个channel 合并成一个channel 返回
	or = func(chs ...<-chan interface{}) <-chan interface{} {
		// 因为有递归调用,所以需要一个跳出条件
		switch len(chs) {
		case 0:
			// 如果没有传参,则直接返回一个nil
			return nil
		case 1:
			//如果只有一个参数channel,则将该参数channel返回即可
			return chs[0]
		}
		// 初始化done通知channel
		orDone := make(chan interface{})
		go func() {
			// 完成后 关闭orChan
			defer close(orDone)
			switch len(chs) {
			case 2:
				select {
				case <-chs[0]:
				case <-chs[1]:
				}
			default:
				select {
				case <-chs[0]:
				case <-chs[1]:
				case <-chs[2]:
				// 将其余的channel参数递归传入到or方法中
				case <-or(append(chs[3:], orDone)...):
				}
			}
		}()
		return orDone
	}
	doWork := func(after time.Duration) <-chan interface{} {
		c := make(chan interface{})
		go func() {
			// 规定时间过后,关闭channel
			defer close(c)
			time.Sleep(after)
		}()
		return c
	}
	t := time.Now()
	defer func(time.Time) {
		// 打印方法执行时间
		fmt.Println(fmt.Sprintf("cost:%s", time.Since(t)))
	}(t)
	<-or(
		doWork(time.Second*5),
		doWork(time.Second*3),
		doWork(time.Minute*2),
		doWork(time.Hour*2),
	)

}

分析

该实例通过将所有的channel都放在不同的goroutine中,通过go语言的协程机制获取到多个channel最先退出的那一个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值