event
Go 实现的轻量级的事件管理、调度工具库
*
来进行一组事件的匹配监听.
ModeSimple
- 注册 app.*
事件的监听,触发 app.run
app.end
时,都将同时会触发 app.*
监听器ModePath
- NEW *
只匹配一段非 .
的字符,可以进行更精细的监听; **
匹配任意多个字符,只能用于开头或结尾*
来监听全部事件的触发chan
, 异步进行消费处理. 触发: Async(), FireAsync()
> 95%
English introduction, please see EN README
go get github.com/gookit/event
On/Listen(name string, listener Listener, priority ...int)
注册事件监听Subscribe/AddSubscriber(sbr Subscriber)
订阅,支持注册多个事件监听Trigger/Fire(name string, params M) (error, Event)
触发事件MustTrigger/MustFire(name string, params M) Event
触发事件,有错误则会panicFireEvent(e Event) (err error)
根据给定的事件实例,触发事件FireBatch(es ...interface{}) (ers []error)
一次触发多个事件Async/FireC(name string, params M)
投递事件到 chan
,异步消费处理FireAsync(e Event)
投递事件到 chan
,异步消费处理AsyncFire(e Event)
简单的通过 go
异步触发事件package main
import (
"fmt"
"github.com/gookit/event"
)
func main() {
// 注册事件监听器
event.On("evt1", event.ListenerFunc(func(e event.Event) error {
fmt.Printf("handle event: %s\n", e.Name())
return nil
}), event.Normal)
// 注册多个监听器
event.On("evt1", event.ListenerFunc(func(e event.Event) error {
fmt.Printf("handle event: %s\n", e.Name())
return nil
}), event.High)
// ... ...
// 触发事件
// 注意:第二个监听器的优先级更高,所以它会先被执行
event.MustFire("evt1", event.M{"arg0": "val0", "arg1": "val1"})
}
Note: 注意:第二个监听器的优先级更高,所以它会先被执行
ModeSimple
是默认模式, 注册事件监听器和名称以通配符 *
结尾:
func main() {
dbListener1 := event.ListenerFunc(func(e event.Event) error {
fmt.Printf("handle event: %s\n", e.Name())
return nil
})
event.On("app.db.*", dbListener1, event.Normal)
}
在其他逻辑上触发事件:
func doCreate() {
// do something ...
// Trigger event
event.MustFire("app.db.create", event.M{"arg0": "val0", "arg1": "val1"})
}
func doUpdate() {
// do something ...
// Trigger event
event.MustFire("app.db.update", event.M{"arg0": "val0"})
}
像上面这样,触发 app.db.create
app.db.update
事件,都会触发执行 dbListener1
监听器.
ModePath
是 v1.1.0
新增的模式,通配符 *
匹配逻辑有调整:
*
只匹配一段非 .
的字符,可以进行更精细的监听匹配**
则匹配任意多个字符,并且只能用于开头或结尾em := event.NewManager("test", event.UsePathMode)
// 注册事件监听器
em.On("app.**", appListener)
em.On("app.db.*", dbListener)
em.On("app.*.create", createListener)
em.On("app.*.update", updateListener)
// ... ...
// 触发事件
// TIP: 将会触发 appListener, dbListener, createListener
em.Fire("app.db.create", event.M{"arg0": "val0", "arg1": "val1"})
chan
消费事件可以使用 Async/FireC/FireAsync
方法触发事件,事件将会写入 chan
异步消费。可以使用 CloseWait()
关闭chan并等待事件全部消费完成。
Note:
event.NewBasic()/event.New()
可以创建通用的Event实例;Async/FireC
无需构建 Event,内部根据参数构建的。
新增配置选项:
ChannelSize
设置 chan
的缓冲大小ConsumerNum
设置启动多少个协程来消费事件func main() {
// 注意:在程序退出时关闭事件chan
// defer event.Close()
defer event.CloseWait()
// 注册事件监听器
event.On("app.evt1", event.ListenerFunc(func(e event.Event) error {
fmt.Printf("handle event: %s\n", e.Name())
return nil
}), event.Normal)
// 注册多个监听器
event.On("app.evt1", event.ListenerFunc(func(e event.Event) error {
fmt.Printf("handle event: %s\n", e.Name())
return nil
}), event.High)
// ... ...
// 异步消费事件
event.FireC("app.evt1", event.M{"arg0": "val0", "arg1": "val1"})
event.FireAsync(event.New("app.evt1", event.M{"arg0": "val2"})
}
Note: 应当在程序退出时关闭事件chan. 可以使用下面的方法:
event.Close()
立即关闭 chan
不再接受新的事件event.CloseWait()
关闭 chan
并等待所有事件处理完成package mypgk
import (
"fmt"
"github.com/gookit/event"
)
var fnHandler = func(e event.Event) error {
fmt.Printf("handle event: %s\n", e.Name())
return nil
}
func Run() {
// register
event.On("evt1", event.ListenerFunc(fnHandler), event.High)
}
interface:
// Listener interface
type Listener interface {
Handle(e Event) error
}
示例:
实现接口
event.Listener
package mypgk
import (
"fmt"
"github.com/gookit/event"
)
type MyListener struct {
// userData string
}
func (l *MyListener) Handle(e event.Event) error {
e.Set("result", "OK")
return nil
}
interface:
// Subscriber event subscriber interface.
// you can register multi event listeners in a struct func.
type Subscriber interface {
// SubscribedEvents register event listeners
// key: is event name
// value: can be Listener or ListenerItem interface
SubscribedEvents() map[string]interface{}
}
示例
实现接口
event.Subscriber
package mypgk
import (
"fmt"
"github.com/gookit/event"
)
type MySubscriber struct {
// ooo
}
func (s *MySubscriber) SubscribedEvents() map[string]interface{} {
return map[string]interface{}{
"e1": event.ListenerFunc(s.e1Handler),
"e2": event.ListenerItem{
Priority: event.AboveNormal,
Listener: event.ListenerFunc(func(e Event) error {
return fmt.Errorf("an error")
}),
},
"e3": &MyListener{},
}
}
func (s *MySubscriber) e1Handler(e event.Event) error {
e.Set("e1-key", "val1")
return nil
}
如果你希望自定义事件对象或者提前定义好一些固定事件信息,可以实现 event.Event
接口.
interface:
// Event interface
type Event interface {
Name() string
// Target() interface{}
Get(key string) interface{}
Add(key string, val interface{})
Set(key string, val interface{})
Data() map[string]interface{}
SetData(M) Event
Abort(bool)
IsAborted() bool
}
示例
package mypgk
import (
"fmt"
"github.com/gookit/event"
)
type MyEvent struct{
event.BasicEvent
customData string
}
func (e *MyEvent) CustomData() string {
return e.customData
}
使用:
e := &MyEvent{customData: "hello"}
e.SetName("e1")
event.AddEvent(e)
// add listener
event.On("e1", event.ListenerFunc(func(e event.Event) error {
fmt.Printf("custom Data: %s\n", e.(*MyEvent).CustomData())
return nil
}))
// trigger
event.Fire("e1", nil)
// OR
// event.FireEvent(e)
Note:
AddEvent()
是用于添加预先定义的公共事件信息,都是在初始化阶段添加,所以没加锁. 在业务中动态创建的Event可以直接使用FireEvent()
触发
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。