观察者和事件
Observers and Events
什么是 Context 事件?
Context 事件是当绑定被添加或移除时由 Context 发出的通知。这些事件允许您对 Context 中的变化做出反应,例如当新服务被注册或配置被更新时。
Context 发出以下事件:
bind
:当新绑定添加到上下文时发出unbind
:当现有绑定从上下文中移除时发出error
:当观察者在通知过程中抛出错误时发出
Context 事件监听器
您可以使用标准的事件发射器模式监听上下文事件。
import { Context } from 'contexify';
const context = new Context('my-context');
// Listen for 'bind' events
context.on('bind', event => {
console.log(`Binding added: ${event.binding.key}`);
});
// Listen for 'unbind' events
context.on('unbind', event => {
console.log(`Binding removed: ${event.binding.key}`);
});
// Add a binding
context.bind('greeting').to('Hello, world!');
// Output: Binding added: greeting
// Remove a binding
context.unbind('greeting');
// Output: Binding removed: greeting
什么是 Context 观察者?
Context 观察者提供了一种更结构化的方式来响应上下文事件。与事件监听器不同,观察者:
- 可以过滤它们感兴趣的绑定
- 可以执行异步操作
- 以受控方式接收通知
上下文观察者是实现 ContextObserver
接口的对象:
interface ContextObserver {
// An optional filter function to match bindings
filter?: BindingFilter;
// Listen on 'bind', 'unbind', or other events
observe(eventType: string, binding: Readonly<Binding<unknown>>, context: Context): ValueOrPromise<void>;
}
创建和使用 Context 观察者
以下是创建和使用上下文观察者的示例:
import { Context, ContextObserver } from 'contexify';
const context = new Context('my-context');
// Create an observer
const serviceObserver: ContextObserver = {
// Only interested in bindings with 'service' tag
filter: binding => binding.tagMap.service != null,
observe(event, binding, ctx) {
if (event === 'bind') {
console.log(`Service registered: ${binding.key}`);
// You can perform async operations here
return registerServiceWithRegistry(binding.key);
} else if (event === 'unbind') {
console.log(`Service unregistered: ${binding.key}`);
return unregisterServiceFromRegistry(binding.key);
}
}
};
// Register the observer
context.subscribe(serviceObserver);
// Add a binding with 'service' tag
context.bind('services.UserService')
.toClass(UserService)
.tag('service');
// Output: Service registered: services.UserService
观察者函数
如果您不需要过滤功能,可以使用简单的函数作为观察者:
import { Context } from 'contexify';
const context = new Context('my-context');
// Create an observer function
const observerFn = (event, binding, ctx) => {
console.log(`Event: ${event}, Binding: ${binding.key}`);
};
// Register the observer function
context.subscribe(observerFn);
Context 视图
Context 视图是建立在观察者之上的更高级抽象。它们允许您跟踪匹配特定过滤器的一组绑定并获取其解析值。
import { Context } from 'contexify';
const context = new Context('my-context');
// Create a view that tracks all bindings with 'controller' tag
const controllersView = context.createView(
binding => binding.tagMap.controller != null
);
// Get all controller instances
async function getControllers() {
const controllers = await controllersView.values();
return controllers;
}
// Add a controller
context.bind('controllers.UserController')
.toClass(UserController)
.tag('controller');
// Now getControllers() will include UserController
Context 视图事件
当绑定从视图中添加或移除时,Context 视图会发出事件:
import { Context } from 'contexify';
const context = new Context('my-context');
const controllersView = context.createView(
binding => binding.tagMap.controller != null
);
// Listen for 'refresh' events
controllersView.on('refresh', () => {
console.log('Controllers view refreshed');
});
// Listen for 'resolve' events
controllersView.on('resolve', () => {
console.log('Controllers view resolved');
});
观察者错误处理
上下文观察者抛出的错误通过上下文链报告:
- 如果链中的任何上下文有
error
监听器,则在该上下文上发出error
事件 - 如果没有上下文有
error
监听器,则在当前上下文上发出error
事件,这可能导致进程退出
建议在观察者中处理错误:
const observer: ContextObserver = {
filter: binding => binding.tagMap.service != null,
observe(event, binding, ctx) {
try {
// Your observer logic
} catch (error) {
console.error('Error in observer:', error);
// Handle the error
}
}
};
最佳实践
- 使用观察者进行组件的动态发现
- 保持观察者专注于单一关注点
- 在观察者中正确处理错误
- 使用上下文视图跟踪相关绑定
- 注意观察者对性能的影响,特别是对于频繁变化的绑定
- 在不再需要上下文视图时关闭它们以避免内存泄漏
下一步
现在您已经了解了观察者和事件,可以了解: