golang全局事件触发器插件库go-trigger的使用

golang全局事件触发器插件库go-trigger的使用

简介

Go Trigger是一个Golang的全局事件触发器。你可以定义一个事件并为其指定任务,然后从任何地方触发它。

安装

$ go get -u github.com/sadlil/go-trigger

如何使用

1. 全局事件

导入包到你的代码中。使用trigger.On方法添加事件,使用trigger.Fire方法调用事件处理器。所有这样添加的事件都是全局事件,可以从任何地方调用Fire

package main

import (
  "github.com/sadlil/go-trigger"
  "fmt"
)

func main() {
  // 添加一个事件
  trigger.On("first-event", func() {
    // 在这里执行任务
    fmt.Println("Done")
  })
  // 触发事件
  trigger.Fire("first-event")
}

你也可以从另一个包中定义事件:

trigger.On("second-event", packagename.FunctionName)
trigger.Fire("second-event")

可以定义带参数和返回类型的事件:

func TestFunc(a, b int) int {
    return a + b
}

// 调用方式
trigger.On("third-event", TestFunc)
values, err := trigger.Fire("third-event", 5, 6)

// 重要:你需要使用类型转换返回值
// values[0].Int()

你可以在一个包中定义事件,在另一个包中触发它。事件和触发器都是全局的。定义在任何地方,触发在任何地方。

//---------------------------------------------
package a

func AFunction(one, two int) int {
    return one + two
}

//---------------------------------------------
package b
import (
    "yourdirectory/a"
    "github.com/sadlil/go-trigger"
)

func() {
    trigger.On("new-event", a.AFunction)
}

//---------------------------------------------
package c
import (
    "github.com/sadlil/go-trigger"
)

func() {
    values, err := trigger.Fire("new-event", 10, 10) 
    // 这里不需要导入包a
    fmt.Println(values[0].Int())
}

可以使用FireBackground()在后台运行事件:

func main() {
  trigger.On("first-event", func() {
    for i := 1; i <= 1000; i++ {
      fmt.Println(i)
    }
  })
  channel, err := trigger.FireBackground("first-event")
  fmt.Println("Event runs")
  // 读取返回的通道
  values := <- channel
  
  trigger.FireBackground("first-event")
  fmt.Println("Running 2nd Event")
}

2. 本地事件

Trigger实例不会影响全局事件。所有添加到本地事件实例的事件只能通过该触发器实例调用。这是可插拔Trigger接口的实现。

创建一个本地触发器实例:

package main

import (
  "github.com/sadlil/go-trigger"
  "fmt"
)

func main() {
  t := trigger.New()
  t.On("first-event", func() {
    // 在这里执行任务
    fmt.Println("Done")
  })
  t.Fire("first-event")
  
  // t2是另一个与t1分离的触发器实例
  t2 := trigger.New()
  t2.On("first-event", func() {
    // 在这里执行任务
    fmt.Println("Done")
  })
  t2.Fire("first-event")
}

可用方法

On(event string, task interface{}) error
  - 添加一个事件。task必须是函数。如果事件重复则抛出错误。
   
Fire(event string, params ...interface{}) ([]reflect.Value, error)
  - 触发指定事件的任务。params是参数,[]是任务的返回值。Fire触发事件并等待它结束,直到执行后续代码。
  
FireBackground(event string, params ...interface{}) (chan []reflect.Value, error)
  - 触发指定事件的任务。与Fire不同,它在go routine中后台运行事件。它触发事件但不等待事件结束。它将事件的返回值写入通道并返回reflect.Values的通道。你可以通过读取通道获取返回值(例如 ret := <- returned channel)。
  
  - 由于FireBackground不等待事件首先结束,如果你的程序退出,它将停止任何未完成的运行事件。因此请确保你的后台事件在程序结束前退出。

Clear(event string) error
  - 从事件列表中删除一个事件。如果未找到事件则抛出错误。
  
ClearEvents()
  - 从事件列表中删除所有事件。
  
HasEvent(event string) bool
  - 检查事件是否存在。如果事件列表中有该键的事件则返回true。否则返回false。
  
Events() []string
  - 返回所有添加的事件。
  
EventCount() int
  - 返回事件的计数。如果没有找到则返回0。

开发中的特性

  1. 一个事件的多个事件处理器

许可证

Licenced under MIT Licence

任何建议和错误报告都将非常感激。


更多关于golang全局事件触发器插件库go-trigger的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang全局事件触发器插件库go-trigger的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-trigger 全局事件触发器插件库使用指南

go-trigger 是一个轻量级的 Golang 全局事件触发器库,它允许你在应用中实现发布/订阅模式,方便不同模块间的解耦通信。

安装

go get github.com/sadlil/go-trigger

基本用法

1. 初始化

import "github.com/sadlil/go-trigger"

// 不需要显式初始化,直接使用即可

2. 注册事件监听器

// 注册一个事件监听器
trigger.On("user.created", func(params ...interface{}) {
    if len(params) > 0 {
        userID, ok := params[0].(int)
        if ok {
            fmt.Printf("新用户创建事件触发,用户ID: %d\n", userID)
        }
    }
})

3. 触发事件

// 触发事件并传递参数
trigger.Fire("user.created", 12345)

// 可以传递多个参数
trigger.Fire("order.placed", "order123", 99.99, time.Now())

4. 异步触发事件

// 异步触发事件,不会阻塞当前goroutine
trigger.FireBackground("user.loggedin", 12345)

5. 移除事件监听器

// 移除特定事件的所有监听器
trigger.Off("user.created")

// 移除所有事件监听器
trigger.Clear()

高级用法

1. 带返回值的事件处理

trigger.On("calculate.sum", func(params ...interface{}) interface{} {
    if len(params) >= 2 {
        a, ok1 := params[0].(int)
        b, ok2 := params[1].(int)
        if ok1 && ok2 {
            return a + b
        }
    }
    return 0
})

result := trigger.Fire("calculate.sum", 10, 20)
fmt.Println("计算结果:", result) // 输出: 计算结果: 30

2. 多个监听器处理同一事件

// 监听器1
trigger.On("order.completed", func(params ...interface{}) {
    orderID := params[0].(string)
    fmt.Printf("[通知系统] 订单 %s 已完成\n", orderID)
})

// 监听器2
trigger.On("order.completed", func(params ...interface{}) {
    orderID := params[0].(string)
    fmt.Printf("[日志系统] 记录订单 %s 完成事件\n", orderID)
})

// 触发事件
trigger.Fire("order.completed", "order-2023-001")

3. 错误处理

trigger.On("data.process", func(params ...interface{}) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("事件处理发生panic:", r)
        }
    }()
    
    // 事件处理逻辑
    // ...
})

实际应用示例

用户注册流程

package main

import (
	"fmt"
	"github.com/sadlil/go-trigger"
)

func main() {
	// 注册事件监听器
	trigger.On("user.register", sendWelcomeEmail)
	trigger.On("user.register", initUserProfile)
	trigger.On("user.register", addToMarketingList)
	
	// 模拟用户注册
	registerUser("user@example.com", "password123")
}

func registerUser(email, password string) {
	// 用户注册逻辑...
	fmt.Println("用户注册成功:", email)
	
	// 触发注册事件
	trigger.Fire("user.register", email)
}

func sendWelcomeEmail(params ...interface{}) {
	email := params[0].(string)
	fmt.Printf("发送欢迎邮件到: %s\n", email)
}

func initUserProfile(params ...interface{}) {
	email := params[0].(string)
	fmt.Printf("初始化用户配置文件: %s\n", email)
}

func addToMarketingList(params ...interface{}) {
	email := params[0].(string)
	fmt.Printf("将用户添加到营销列表: %s\n", email)
}

注意事项

  1. go-trigger 是全局单例模式,适合中小型应用
  2. 对于高性能场景,可能需要考虑更专业的事件总线库
  3. 事件名称是字符串,建议使用常量或枚举来管理
  4. 参数传递时要注意类型断言的安全性
  5. 大量使用可能增加调试复杂度,需权衡利弊

go-trigger 提供了一种简单的方式来实现组件间的解耦通信,特别适合插件式架构或需要松散耦合的场景。

回到顶部