JSBox 组件间复杂交互与数据同步完全指南
在大型 JSBox 应用中,组件间的交互和数据同步是最具挑战性的问题之一。当多个组件需要共享状态、响应彼此的变化时,如何设计一个清晰、高效、可维护的架构就显得尤为重要。
一、组件交互模式概览
1. 交互复杂度的层次
组件间的交互可以分为不同的复杂度层次:
// 简单交互:单向数据流
// A -> B
componentA.emit('data:updated', data);
componentB.on('data:updated', (data) => { /* 处理 */ });
// 中等复杂度:双向交互
// A <-> B
componentA.on('request:data', () => {
componentB.emit('response:data', data);
});
// 高复杂度:多组件协同
// A -> B -> C
// \-> D -> E
// 需要更复杂的协调机制
2. 核心挑战
- 状态一致性:确保多个组件显示的数据保持同步
- 时序问题:处理异步操作的顺序和依赖
- 性能优化:避免不必要的更新和渲染
- 错误恢复:一个组件出错不应影响整个系统
- 可维护性:交互逻辑要清晰、可追踪
二、高级组件通信架构
1. 中介者模式(Mediator Pattern)
中介者模式通过一个中心协调器来管理组件间的交互:
class ComponentMediator {
constructor() {
this.components = new Map();
this.interactions = new Map();
this.state = {};
}
// 注册组件
register(id, component) {
this.components.set(id, component);
// 为组件注入通信方法
component.mediator = {
send: (target, message, data) => {
this.send(id, target, message, data);
},
broadcast: (message, data) => {
this.broadcast(id, message, data);
},
request: (target, message, data) => {
return this.request(id, target, message, data);
}
};
return this;
}
// 定义交互规则
defineInteraction(name, config) {
this.interactions.set(name, {
participants: config.participants,
coordinator: config.coordinator,
validators: config.validators || [],
transformers: config.transformers || {}
});
}
// 发送消息
send(from, to, message, data) {
const target = this.components.get(to);
if (!target) {
console.error(`Component ${to} not found`);
return;
}
// 查找适用的交互规则
const interaction = this.findInteraction(from, to, message);
if (interaction) {
// 应用验证器
for (const validator of interaction.validators) {
if (!validator(from, to, message, data)) {
console.warn(`Validation failed for ${message}`);
return;
}
}
// 应用转换器
if (interaction.transformers[message]) {
data = interaction.transformers[message](data);
}
}
// 记录交互历史
this.logInteraction(from, to, message, data);
// 发送消息
if (target.handleMessage) {
target.handleMessage(message, data, from);
}
}
// 广播消息
broadcast(from, message, data) {
this.components.forEach((component, id) => {
if (id !== from) {
this.send(from, id, message, data);
}
});
}
// 请求-响应模式
async request(from, to, message, data) {
return new Promise((resolve, reject) => {
const requestId = this.generateRequestId();
// 设置超时
const timeout = setTimeout(() => {
reject(new Error(`Request timeout: ${message}`));
}, 5000);
// 注册响应处理器
this.once(`response:${requestId}`, (response) => {
clearTimeout(timeout);
resolve(response);
});
// 发送请求
this.send(from, to, message, {
...data,
__requestId: requestId
});
});
}
// 查找适用的交互规则
findInteraction(from, to, message) {
for (const [name, interaction] of this.interactions) {
if (interaction.participants.includes(from) &&
interaction.participants.includes(to)) {
return interaction;
}
}
return null;
}
// 记录交互历史
logInteraction(from, to, message, data) {
if (!this.history) this.history = [];
this.history.push({
from,
to,
message,
data: JSON.parse(JSON.stringify(data)),
timestamp: Date.now()
});
// 限制历史记录大小
if (this.history.length > 1000) {
this.history = this.history.slice(-500);
}
}
generateRequestId() {
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
}
// 使用示例:购物车系统
const mediator = new ComponentMediator();
// 定义交互规则
mediator.defineInteraction('shopping', {
participants: ['productList', 'cart', 'checkout'],
validators: [
(from, to, message, data) => {
// 验证商品数据
if (message === 'add:product') {
return data.product && data.product.id && data.product.price > 0;
}
return true;
}
],
transformers: {
'add:product': (data) => ({
...data,
addedAt: Date.now()
})
}
});
// 组件实现
class ProductListComponent {
handleProductClick(product) {
this.mediator.send('cart', 'add:product', { product });
}
}
class CartComponent {
constructor() {
this.items = [];
}
handleMessage(message, data, from) {
switch (message) {
case 'add:product':
this.addProduct(data.product);
// 通知其他组件
this.mediator.broadcast('cart:updated', {
itemCount: this.items.length,
total: this.calculateTotal()
});
break;
}
}
}
2. 数据流管理器(Data Flow Manager)
创建一个专门管理数据流的系统:
class DataFlowManager {
constructor() {
this.flows = new Map();
this.subscriptions = new Map();
this.middleware = [];
}
// 定义数据流
defineFlow(name, config) {
const flow = {
name,
source: config.source,
targets: config.targets || [],
transform: config.transform || (data => data),
filter: config.filter || (() => true),
merge: config.merge || ((prev, next) => next),
debounce: config.debounce || 0,
throttle: config.throttle || 0,
cache: config.cache || false,
queue: [],
processing: false
};
this.flows.set(name, flow);
// 设置定时器
if (flow.debounce > 0) {
flow.debounceTimer = null;
}
if (flow.throttle > 0) {
flow.throttleTimer = null;
}
return this;
}
// 发送数据
async send(flowName, data, context = {}) {
const flow = this.flows.get(flowName);
if (!flow) {
throw new Error(`Flow ${flowName} not defined`);
}
// 应用中间件
let processedData = data;
for (const middleware of this.middleware) {
processedData = await middleware(processedData, flow, context);
}
// 应用过滤器
if (!flow.filter(processedData, context)) {
return;
}
// 处理防抖
if (flow.debounce > 0) {
clearTimeout(flow.debounceTimer);
flow.debounceTimer = setTimeout(() => {
this.processFlow(flow, processedData, context);
}, flow.debounce);
return;
}
// 处理节流
if (flow.throttle > 0) {
if (flow.throttleTimer) return;
flow.throttleTimer = setTimeout(() => {
flow.throttleTimer = null;
}, flow.throttle);
}
// 加入队列
flow.queue.push({ data: processedData, context });
// 处理队列
if (!flow.processing) {
this.processQueue(flow);
}
}
// 处理队列
async processQueue(flow) {
flow.processing = true;
while (flow.queue.length > 0) {
const batch = flow.queue.splice(0, 10); // 批处理
for (const item of batch) {
await this.processFlow(flow, item.data, item.context);
}
}
flow.processing = false;
}
// 处理数据流
async processFlow(flow, data, context) {
try {
// 应用转换
const transformedData = await flow.transform(data, context);
// 缓存处理
if (flow.cache) {
const cacheKey = this.getCacheKey(flow, transformedData);
if (flow.lastCache && flow.lastCache.key === cacheKey) {
return; // 跳过相同的数据
}
flow.lastCache = { key: cacheKey, data: transformedData };
}
// 分发到目标
for (const target of flow.targets) {
const subscribers = this.subscriptions.get(target) || [];
for (const subscriber of subscribers) {
try {
await subscriber.handler(transformedData, {
...context,
flow: flow.name,
source: flow.source
});
} catch (error) {
console.error(`Error in subscriber:`, error);
if (subscriber.errorHandler) {
subscriber.errorHandler(error, transformedData);
}
}
}
}
} catch (error) {
console.error(`Error in flow ${flow.name}:`, error);
throw error;
}
}
// 订阅数据流
subscribe(target, handler, options = {}) {
if (!this.subscriptions.has(target)) {
this.subscriptions.set(target, []);
}
const subscription = {
handler,
errorHandler: options.errorHandler,
priority: options.priority || 0
};
const subscribers = this.subscriptions.get(target);
subscribers.push(subscription);
// 按优先级排序
subscribers.sort((a, b) => b.priority - a.priority);
// 返回取消订阅函数
return () => {
const index = subscribers.indexOf(subscription);
if (index > -1) {
subscribers.splice(index, 1);
}
};
}
// 添加中间件
use(middleware) {
this.middleware.push(middleware);
return this;
}
// 获取缓存键
getCacheKey(flow, data) {
return JSON.stringify(data);
}
}
// 使用示例:表单联动系统
const dataFlow = new DataFlowManager();
// 定义数据流
dataFlow.defineFlow('formUpdate', {
source: 'form',
targets: ['validation', 'preview', 'autoSave'],
transform: (data) => ({
...data,
timestamp: Date.now()
}),
debounce: 300,
cache: true
});
dataFlow.defineFlow('validationResult', {
source: 'validation',
targets: ['form', 'submitButton'],
transform: (errors) => ({
hasErrors: errors.length > 0,
errors: errors
})
});
// 添加中间件
dataFlow.use(async (data, flow, context) => {
console.log(`Flow ${flow.name}: `, data);
return data;
});
// 组件订阅
class FormComponent {
constructor() {
dataFlow.subscribe('form', (data) => {
if (data.hasErrors) {
this.showErrors(data.errors);
}
});
}
onInputChange(field, value) {
dataFlow.send('formUpdate', {
field,
value,
allValues: this.getFormValues()
});
}
}
3. 状态同步器(State Synchronizer)
处理多个组件间的状态同步:
class StateSynchronizer {
constructor() {
this.stores = new Map();
this.syncRules = new Map();
this.conflicts = [];
this.version = 0;
}
// 创建状态存储
createStore(id, initialState = {}) {
const store = {
id,
state: initialState,
version: 0,
history: [],
locks: new Set()
};
this.stores.set(id, store);
return {
getState: () => this.getState(id),
setState: (updates) => this.setState(id, updates),
subscribe: (handler) => this.subscribe(id, handler),
lock: (key) => this.lock(id, key),
unlock: (key) => this.unlock(id, key)
};
}
// 定义同步规则
defineSyncRule(rule) {
const syncRule = {
id: rule.id,
sources: rule.sources,
target: rule.target,
mapping: rule.mapping || ((states) => Object.assign({}, ...states)),
conflict: rule.conflict || 'last-write-wins',
condition: rule.condition || (() => true),
transform: rule.transform || (data => data)
};
this.syncRules.set(rule.id, syncRule);
// 监听源变化
rule.sources.forEach(source => {
this.subscribe(source, () => {
this.applySyncRule(syncRule);
});
});
}
// 应用同步规则
async applySyncRule(rule) {
// 检查条件
const states = rule.sources.map(id => this.getState(id));
if (!rule.condition(states)) {
return;
}
// 收集源状态
const sourceStates = {};
rule.sources.forEach(id => {
sourceStates[id] = this.getState(id);
});
// 应用映射
let targetState = rule.mapping(sourceStates);
// 应用转换
targetState = await rule.transform(targetState);
// 检测冲突
const conflicts = this.detectConflicts(rule.target, targetState);
if (conflicts.length > 0) {
targetState = this.resolveConflicts(conflicts, rule.conflict, targetState);
}
// 更新目标状态
this.setState(rule.target, targetState, {
source: 'sync',
rule: rule.id
});
}
// 设置状态
setState(id, updates, metadata = {}) {
const store = this.stores.get(id);
if (!store) {
throw new Error(`Store ${id} not found`);
}
// 检查锁
const lockedKeys = Object.keys(updates).filter(key => store.locks.has(key));
if (lockedKeys.length > 0) {
throw new Error(`Keys are locked: ${lockedKeys.join(', ')}`);
}
// 创建新状态
const oldState = store.state;
const newState = this.mergeState(oldState, updates);
// 更新版本
store.version++;
this.version++;
// 保存历史
store.history.push({
version: store.version,
globalVersion: this.version,
oldState,
newState,
updates,
metadata,
timestamp: Date.now()
});
// 限制历史大小
if (store.history.length > 100) {
store.history = store.history.slice(-50);
}
// 更新状态
store.state = newState;
// 通知订阅者
this.notifySubscribers(id, newState, oldState, updates);
}
// 合并状态
mergeState(oldState, updates) {
const newState = { ...oldState };
Object.entries(updates).forEach(([key, value]) => {
if (value === undefined) {
delete newState[key];
} else if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
newState[key] = this.mergeState(oldState[key] || {}, value);
} else {
newState[key] = value;
}
});
return newState;
}
// 检测冲突
detectConflicts(targetId, newState) {
const store = this.stores.get(targetId);
if (!store) return [];
const conflicts = [];
const lastUpdate = store.history[store.history.length - 1];
if (lastUpdate && Date.now() - lastUpdate.timestamp < 100) {
// 检测快速连续更新
Object.keys(newState).forEach(key => {
if (lastUpdate.updates[key] !== undefined) {
conflicts.push({
key,
currentValue: store.state[key],
newValue: newState[key],
lastUpdate: lastUpdate.updates[key]
});
}
});
}
return conflicts;
}
// 解决冲突
resolveConflicts(conflicts, strategy, newState) {
const resolved = { ...newState };
conflicts.forEach(conflict => {
switch (strategy) {
case 'last-write-wins':
// 使用新值
resolved[conflict.key] = conflict.newValue;
break;
case 'merge':
// 尝试合并
if (typeof conflict.currentValue === 'object' &&
typeof conflict.newValue === 'object') {
resolved[conflict.key] = {
...conflict.currentValue,
...conflict.newValue
};
} else if (typeof conflict.currentValue === 'number' &&
typeof conflict.newValue === 'number') {
// 数值相加
resolved[conflict.key] = conflict.currentValue + conflict.newValue;
} else {
resolved[conflict.key] = conflict.newValue;
}
break;
case 'keep-first':
// 保留当前值
resolved[conflict.key] = conflict.currentValue;
break;
default:
// 自定义策略
if (typeof strategy === 'function') {
resolved[conflict.key] = strategy(conflict);
}
}
});
// 记录冲突
this.conflicts.push({
timestamp: Date.now(),
conflicts,
strategy,
resolved
});
return resolved;
}
// 时间旅行
timeTravel(id, version) {
const store = this.stores.get(id);
if (!store) return null;
const historyItem = store.history.find(h => h.version === version);
if (!historyItem) return null;
// 恢复到指定版本
store.state = historyItem.newState;
store.version = version;
// 通知订阅者
this.notifySubscribers(id, historyItem.newState, null, {});
return historyItem.newState;
}
// 订阅相关
subscribe(id, handler) {
if (!this.subscribers) {
this.subscribers = new Map();
}
if (!this.subscribers.has(id)) {
this.subscribers.set(id, []);
}
this.subscribers.get(id).push(handler);
return () => {
const subscribers = this.subscribers.get(id);
const index = subscribers.indexOf(handler);
if (index > -1) {
subscribers.splice(index, 1);
}
};
}
notifySubscribers(id, newState, oldState, updates) {
const subscribers = this.subscribers?.get(id) || [];
subscribers.forEach(handler => {
try {
handler(newState, oldState, updates);
} catch (error) {
console.error('Subscriber error:', error);
}
});
}
}
// 使用示例:多组件表单同步
const synchronizer = new StateSynchronizer();
// 创建状态存储
const formStore = synchronizer.createStore('form', {
name: '',
email: '',
age: 0
});
const validationStore = synchronizer.createStore('validation', {
errors: {},
isValid: true
});
const previewStore = synchronizer.createStore('preview', {
displayName: '',
summary: ''
});
// 定义同步规则
synchronizer.defineSyncRule({
id: 'form-to-validation',
sources: ['form'],
target: 'validation',
mapping: (states) => {
const form = states.form;
const errors = {};
if (!form.name) errors.name = '姓名不能为空';
if (!form.email || !form.email.includes('@')) errors.email = '邮箱格式不正确';
if (form.age < 0 || form.age > 150) errors.age = '年龄不合法';
return {
errors,
isValid: Object.keys(errors).length === 0
};
}
});
synchronizer.defineSyncRule({
id: 'form-to-preview',
sources: ['form'],
target: 'preview',
mapping: (states) => {
const form = states.form;
return {
displayName: form.name || '未填写',
summary: `${form.name}, ${form.age}岁, ${form.email}`
};
},
condition: (states) => states.form.name !== ''
});
三、复杂交互场景处理
1. 主从组件协同
处理主组件控制多个从组件的场景:
class MasterSlaveCoordinator {
constructor() {
this.master = null;
this.slaves = new Map();
this.commands = new Map();
}
// 注册主组件
registerMaster(component) {
this.master = component;
// 注入控制方法
component.control = {
broadcast: (command, data) => this.broadcastCommand(command, data),
execute: (slaveId, command, data) => this.executeCommand(slaveId, command, data),
query: (slaveId, query) => this.querySlaveState(slaveId, query),
coordinate: (task) => this.coordinateTask(task)
};
}
// 注册从组件
registerSlave(id, component) {
const slave = {
id,
component,
state: 'idle',
capabilities: component.capabilities || [],
queue: []
};
this.slaves.set(id, slave);
// 注入响应方法
component.slave = {
reportState: (state) => this.updateSlaveState(id, state),
requestPermission: (action) => this.requestPermission(id, action),
notifyComplete: (taskId) => this.notifyTaskComplete(id, taskId)
};
}
// 定义命令
defineCommand(name, config) {
this.commands.set(name, {
name,
validate: config.validate || (() => true),
prepare: config.prepare || (data => data),
execute: config.execute,
rollback: config.rollback || (() => {}),
timeout: config.timeout || 5000
});
}
// 广播命令
async broadcastCommand(commandName, data) {
const command = this.commands.get(commandName);
if (!command) {
throw new Error(`Command ${commandName} not defined`);
}
// 验证命令
if (!command.validate(data)) {
throw new Error(`Invalid command data`);
}
// 准备数据
const preparedData = await command.prepare(data);
// 执行命令
const results = new Map();
const promises = [];
this.slaves.forEach((slave, id) => {
if (slave.state === 'idle' && this.canExecute(slave, commandName)) {
promises.push(
this.executeOnSlave(slave, command, preparedData)
.then(result => results.set(id, { success: true, result }))
.catch(error => results.set(id, { success: false, error }))
);
}
});
await Promise.all(promises);
return results;
}
// 协调任务
async coordinateTask(task) {
const steps = task.steps || [];
const context = { results: [] };
for (const step of steps) {
try {
const result = await this.executeStep(step, context);
context.results.push({
step: step.name,
success: true,
result
});
if (step.onSuccess) {
await step.onSuccess(result, context);
}
} catch (error) {
context.results.push({
step: step.name,
success: false,
error
});
if (step.onError) {
const shouldContinue = await step.onError(error, context);
if (!shouldContinue) {
break;
}
} else {
break;
}
}
}
return context;
}
// 执行步骤
async executeStep(step, context) {
const targetSlaves = this.selectSlaves(step.target);
if (step.parallel) {
// 并行执行
const promises = targetSlaves.map(slave =>
this.executeCommand(slave.id, step.command, step.data(context))
);
return Promise.all(promises);
} else {
// 串行执行
const results = [];
for (const slave of targetSlaves) {
const result = await this.executeCommand(
slave.id,
step.command,
step.data(context)
);
results.push(result);
}
return results;
}
}
// 选择从组件
selectSlaves(target) {
if (typeof target === 'function') {
return Array.from(this.slaves.values()).filter(target);
} else if (Array.isArray(target)) {
return target.map(id => this.slaves.get(id)).filter(Boolean);
} else if (typeof target === 'string') {
const slave = this.slaves.get(target);
return slave ? [slave] : [];
} else {
return Array.from(this.slaves.values());
}
}
}
// 使用示例:多图表联动系统
const coordinator = new MasterSlaveCoordinator();
// 主控制组件
class DashboardController {
constructor() {
coordinator.registerMaster(this);
}
async updateTimeRange(range) {
// 广播时间范围更新
const results = await this.control.broadcast('updateTimeRange', range);
// 检查结果
results.forEach((result, slaveId) => {
if (!result.success) {
console.error(`Chart ${slaveId} update failed:`, result.error);
}
});
}
async exportAllCharts() {
// 协调导出任务
const task = {
steps: [
{
name: 'prepare',
target: (slave) => slave.capabilities.includes('export'),
command: 'prepareExport',
data: () => ({ format: 'png' }),
parallel: true
},
{
name: 'render',
target: (slave) => slave.capabilities.includes('export'),
command: 'renderChart',
data: (context) => ({
quality: 'high',
prepared: context.results[0].result
}),
parallel: false
},
{
name: 'collect',
target: 'master',
command: 'collectExports',
data: (context) => ({
charts: context.results[1].result
})
}
]
};
const result = await this.control.coordinate(task);
return result;
}
}
// 从组件:图表
class ChartComponent {
constructor(id, type) {
this.capabilities = ['update', 'export', 'zoom'];
coordinator.registerSlave(id, this);
}
async handleCommand(command, data) {
switch (command) {
case 'updateTimeRange':
await this.updateData(data);
this.slave.reportState('updated');
break;
case 'prepareExport':
const prepared = await this.prepareForExport(data.format);
return prepared;
case 'renderChart':
const rendered = await this.render(data);
return rendered;
}
}
}
2. 事务性操作
确保多个组件的操作要么全部成功,要么全部失败:
class TransactionManager {
constructor() {
this.transactions = new Map();
this.participants = new Map();
}
// 开始事务
async beginTransaction(id, options = {}) {
const transaction = {
id,
state: 'active',
participants: new Set(),
operations: [],
rollbacks: [],
timeout: options.timeout || 30000,
startTime: Date.now(),
context: {}
};
this.transactions.set(id, transaction);
// 设置超时
transaction.timeoutHandle = setTimeout(() => {
this.rollbackTransaction(id, new Error('Transaction timeout'));
}, transaction.timeout);
return {
id,
addOperation: (operation) => this.addOperation(id, operation),
commit: () => this.commitTransaction(id),
rollback: (reason) => this.rollbackTransaction(id, reason)
};
}
// 添加操作
addOperation(transactionId, operation) {
const transaction = this.transactions.get(transactionId);
if (!transaction || transaction.state !== 'active') {
throw new Error('Transaction not active');
}
const op = {
id: `${transactionId}_op_${transaction.operations.length}`,
component: operation.component,
execute: operation.execute,
rollback: operation.rollback,
validate: operation.validate || (() => true),
state: 'pending'
};
transaction.operations.push(op);
transaction.participants.add(operation.component);
return op.id;
}
// 提交事务
async commitTransaction(id) {
const transaction = this.transactions.get(id);
if (!transaction || transaction.state !== 'active') {
throw new Error('Transaction not active');
}
transaction.state = 'committing';
try {
// 验证所有操作
for (const op of transaction.operations) {
if (!await op.validate(transaction.context)) {
throw new Error(`Validation failed for operation ${op.id}`);
}
}
// 执行所有操作
for (const op of transaction.operations) {
try {
op.state = 'executing';
const result = await op.execute(transaction.context);
op.state = 'completed';
op.result = result;
// 保存回滚信息
if (op.rollback) {
transaction.rollbacks.push({
operation: op,
data: result
});
}
} catch (error) {
op.state = 'failed';
op.error = error;
throw error;
}
}
// 事务成功
transaction.state = 'committed';
clearTimeout(transaction.timeoutHandle);
// 通知参与者
this.notifyParticipants(transaction, 'committed');
return {
success: true,
results: transaction.operations.map(op => op.result)
};
} catch (error) {
// 回滚事务
await this.rollbackTransaction(id, error);
throw error;
}
}
// 回滚事务
async rollbackTransaction(id, reason) {
const transaction = this.transactions.get(id);
if (!transaction) return;
transaction.state = 'rolling-back';
clearTimeout(transaction.timeoutHandle);
// 反向执行回滚操作
for (let i = transaction.rollbacks.length - 1; i >= 0; i--) {
const { operation, data } = transaction.rollbacks[i];
try {
await operation.rollback(data, transaction.context);
} catch (error) {
console.error(`Rollback failed for operation ${operation.id}:`, error);
}
}
transaction.state = 'rolled-back';
transaction.rollbackReason = reason;
// 通知参与者
this.notifyParticipants(transaction, 'rolled-back', reason);
return {
success: false,
reason: reason.message || reason
};
}
// 通知参与者
notifyParticipants(transaction, event, data) {
transaction.participants.forEach(component => {
if (component.onTransactionEvent) {
component.onTransactionEvent(transaction.id, event, data);
}
});
}
}
// 使用示例:购物下单流程
async function processOrder(orderData) {
const tm = new TransactionManager();
const transaction = await tm.beginTransaction('order_' + Date.now());
try {
// 扣减库存
transaction.addOperation({
component: inventoryComponent,
execute: async (context) => {
const result = await inventoryComponent.decreaseStock(orderData.items);
context.stockReservation = result.reservationId;
return result;
},
rollback: async (result, context) => {
await inventoryComponent.releaseStock(result.reservationId);
},
validate: async () => {
return await inventoryComponent.checkStock(orderData.items);
}
});
// 创建订单
transaction.addOperation({
component: orderComponent,
execute: async (context) => {
const order = await orderComponent.createOrder({
...orderData,
stockReservation: context.stockReservation
});
context.orderId = order.id;
return order;
},
rollback: async (order) => {
await orderComponent.cancelOrder(order.id);
}
});
// 扣款
transaction.addOperation({
component: paymentComponent,
execute: async (context) => {
const payment = await paymentComponent.processPayment({
orderId: context.orderId,
amount: orderData.totalAmount,
method: orderData.paymentMethod
});
return payment;
},
rollback: async (payment) => {
await paymentComponent.refund(payment.id);
},
validate: async () => {
return await paymentComponent.validatePaymentMethod(orderData.paymentMethod);
}
});
// 提交事务
const result = await transaction.commit();
console.log('Order processed successfully:', result);
return result;
} catch (error) {
console.error('Order processing failed:', error);
throw error;
}
}
3. 分布式状态管理
处理跨设备或跨会话的状态同步:
class DistributedStateManager {
constructor(options = {}) {
this.nodeId = options.nodeId || this.generateNodeId();
this.peers = new Map();
this.state = {};
this.vector = new Map(); // 向量时钟
this.operations = []; // 操作日志
this.conflictResolver = options.conflictResolver || this.defaultConflictResolver;
}
// 生成节点ID
generateNodeId() {
return `node_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// 连接到对等节点
connectPeer(peerId, connection) {
this.peers.set(peerId, {
id: peerId,
connection,
vector: new Map(),
lastSeen: Date.now()
});
// 同步初始状态
this.syncWithPeer(peerId);
}
// 更新本地状态
updateState(path, value, metadata = {}) {
// 增加向量时钟
this.incrementVector(this.nodeId);
// 创建操作
const operation = {
id: this.generateOperationId(),
type: 'update',
path,
value,
nodeId: this.nodeId,
vector: new Map(this.vector),
timestamp: Date.now(),
metadata
};
// 应用操作
this.applyOperation(operation);
// 广播给其他节点
this.broadcastOperation(operation);
}
// 应用操作
applyOperation(operation) {
// 检查是否已经应用过
if (this.operations.find(op => op.id === operation.id)) {
return;
}
// 检查因果关系
if (!this.checkCausality(operation)) {
// 延迟应用
this.deferOperation(operation);
return;
}
// 检测冲突
const conflicts = this.detectConflicts(operation);
if (conflicts.length > 0) {
// 解决冲突
const resolved = this.conflictResolver(operation, conflicts, this.state);
if (!resolved) return;
operation = resolved;
}
// 应用到状态
this.applyToState(operation);
// 更新向量时钟
this.mergeVector(operation.vector);
// 保存操作日志
this.operations.push(operation);
// 触发状态变化事件
this.onStateChange(operation.path, operation.value, operation);
// 检查延迟的操作
this.checkDeferredOperations();
}
// 检查因果关系
checkCausality(operation) {
for (const [nodeId, clock] of operation.vector) {
if (nodeId === operation.nodeId) continue;
const localClock = this.vector.get(nodeId) || 0;
if (clock > localClock + 1) {
return false; // 缺少前置操作
}
}
return true;
}
// 检测冲突
detectConflicts(operation) {
const conflicts = [];
// 查找并发操作
for (const existingOp of this.operations) {
if (existingOp.path === operation.path &&
this.areConcurrent(existingOp, operation)) {
conflicts.push(existingOp);
}
}
return conflicts;
}
// 判断是否并发
areConcurrent(op1, op2) {
const v1 = op1.vector;
const v2 = op2.vector;
// 检查是否有因果关系
let v1BeforeV2 = true;
let v2BeforeV1 = true;
for (const [nodeId, clock1] of v1) {
const clock2 = v2.get(nodeId) || 0;
if (clock1 > clock2) v2BeforeV1 = false;
if (clock1 < clock2) v1BeforeV2 = false;
}
for (const [nodeId, clock2] of v2) {
if (!v1.has(nodeId) && clock2 > 0) {
v1BeforeV2 = false;
}
}
// 如果都不在对方之前,则是并发的
return !v1BeforeV2 && !v2BeforeV1;
}
// 默认冲突解决器
defaultConflictResolver(newOp, conflicts, currentState) {
// Last-Write-Wins with timestamp
const allOps = [...conflicts, newOp];
const latestOp = allOps.reduce((latest, op) =>
op.timestamp > latest.timestamp ? op : latest
);
return latestOp;
}
// CRDT 数据类型
createCRDT(type) {
switch (type) {
case 'counter':
return new CRDTCounter(this);
case 'set':
return new CRDTSet(this);
case 'map':
return new CRDTMap(this);
default:
throw new Error(`Unknown CRDT type: ${type}`);
}
}
}
// CRDT 计数器
class CRDTCounter {
constructor(stateManager) {
this.stateManager = stateManager;
this.increments = new Map();
this.decrements = new Map();
}
increment(amount = 1) {
const nodeId = this.stateManager.nodeId;
const current = this.increments.get(nodeId) || 0;
this.increments.set(nodeId, current + amount);
this.stateManager.updateState('counter', {
type: 'counter',
increments: Array.from(this.increments),
decrements: Array.from(this.decrements)
});
}
decrement(amount = 1) {
const nodeId = this.stateManager.nodeId;
const current = this.decrements.get(nodeId) || 0;
this.decrements.set(nodeId, current + amount);
this.stateManager.updateState('counter', {
type: 'counter',
increments: Array.from(this.increments),
decrements: Array.from(this.decrements)
});
}
getValue() {
let total = 0;
for (const [_, value] of this.increments) {
total += value;
}
for (const [_, value] of this.decrements) {
total -= value;
}
return total;
}
merge(other) {
// 合并增量
for (const [nodeId, value] of other.increments) {
const current = this.increments.get(nodeId) || 0;
this.increments.set(nodeId, Math.max(current, value));
}
// 合并减量
for (const [nodeId, value] of other.decrements) {
const current = this.decrements.get(nodeId) || 0;
this.decrements.set(nodeId, Math.max(current, value));
}
}
}
// 使用示例:协作编辑器
class CollaborativeEditor {
constructor() {
this.dsm = new DistributedStateManager({
nodeId: $device.info.name,
conflictResolver: this.resolveEditConflict.bind(this)
});
this.setupWebSocket();
}
setupWebSocket() {
this.ws = new WebSocket('wss://collab.example.com');
this.ws.onmessage = (event) => {
const { type, data } = JSON.parse(event.data);
switch (type) {
case 'operation':
this.dsm.applyOperation(data);
break;
case 'sync':
this.handleSync(data);
break;
}
};
// 监听本地操作
this.dsm.onBroadcast = (operation) => {
this.ws.send(JSON.stringify({
type: 'operation',
data: operation
}));
};
}
insertText(position, text) {
this.dsm.updateState('document', {
type: 'insert',
position,
text,
length: text.length
});
}
deleteText(position, length) {
this.dsm.updateState('document', {
type: 'delete',
position,
length
});
}
resolveEditConflict(newOp, conflicts, currentState) {
// 操作转换算法
let transformedOp = { ...newOp };
for (const conflict of conflicts) {
if (conflict.value.type === 'insert' && newOp.value.type === 'insert') {
if (conflict.value.position <= newOp.value.position) {
transformedOp.value.position += conflict.value.length;
}
} else if (conflict.value.type === 'delete' && newOp.value.type === 'insert') {
if (conflict.value.position < newOp.value.position) {
transformedOp.value.position -= conflict.value.length;
}
}
// 更多转换规则...
}
return transformedOp;
}
}
四、性能优化策略
1. 批处理和调度
优化大量组件更新的性能:
class BatchScheduler {
constructor() {
this.queues = new Map();
this.processors = new Map();
this.running = false;
}
// 注册处理器
registerProcessor(type, processor) {
this.processors.set(type, {
process: processor.process,
batchSize: processor.batchSize || 10,
priority: processor.priority || 0,
delay: processor.delay || 0
});
}
// 添加任务
schedule(type, task) {
if (!this.queues.has(type)) {
this.queues.set(type, []);
}
this.queues.get(type).push({
task,
timestamp: Date.now()
});
if (!this.running) {
this.startProcessing();
}
}
// 开始处理
async startProcessing() {
this.running = true;
while (this.hasWork()) {
// 按优先级排序队列
const sortedTypes = Array.from(this.processors.keys()).sort((a, b) => {
const procA = this.processors.get(a);
const procB = this.processors.get(b);
return procB.priority - procA.priority;
});
for (const type of sortedTypes) {
await this.processQueue(type);
}
// 短暂休息,让出CPU
await new Promise(resolve => setTimeout(resolve, 0));
}
this.running = false;
}
// 处理队列
async processQueue(type) {
const queue = this.queues.get(type);
if (!queue || queue.length === 0) return;
const processor = this.processors.get(type);
const batch = queue.splice(0, processor.batchSize);
if (processor.delay > 0) {
await new Promise(resolve => setTimeout(resolve, processor.delay));
}
try {
await processor.process(batch.map(item => item.task));
} catch (error) {
console.error(`Batch processing error for ${type}:`, error);
// 重新加入队列末尾
queue.push(...batch);
}
}
hasWork() {
for (const queue of this.queues.values()) {
if (queue.length > 0) return true;
}
return false;
}
}
// 使用示例
const scheduler = new BatchScheduler();
// 注册UI更新处理器
scheduler.registerProcessor('ui-update', {
process: async (updates) => {
$ui.animate({
duration: 0.3,
animation: () => {
updates.forEach(update => {
update.apply();
});
}
});
},
batchSize: 20,
priority: 10,
delay: 16 // 约60fps
});
// 注册数据同步处理器
scheduler.registerProcessor('data-sync', {
process: async (syncs) => {
const grouped = syncs.reduce((acc, sync) => {
if (!acc[sync.target]) acc[sync.target] = [];
acc[sync.target].push(sync.data);
return acc;
}, {});
for (const [target, dataList] of Object.entries(grouped)) {
await syncToTarget(target, dataList);
}
},
batchSize: 50,
priority: 5
});
2. 缓存和记忆化
减少重复计算和请求:
class SmartCache {
constructor(options = {}) {
this.cache = new Map();
this.maxSize = options.maxSize || 100;
this.ttl = options.ttl || 60000; // 默认60秒
this.strategy = options.strategy || 'lru'; // lru, lfu, fifo
this.stats = {
hits: 0,
misses: 0,
evictions: 0
};
}
// 获取或计算
async getOrCompute(key, computeFn, options = {}) {
const cached = this.get(key);
if (cached !== undefined) {
this.stats.hits++;
return cached;
}
this.stats.misses++;
// 防止并发计算
if (this.computing && this.computing.has(key)) {
return this.computing.get(key);
}
if (!this.computing) {
this.computing = new Map();
}
const promise = computeFn().then(result => {
this.set(key, result, options);
this.computing.delete(key);
return result;
}).catch(error => {
this.computing.delete(key);
throw error;
});
this.computing.set(key, promise);
return promise;
}
// 设置缓存
set(key, value, options = {}) {
const ttl = options.ttl || this.ttl;
const priority = options.priority || 0;
// 检查大小限制
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
this.evict();
}
this.cache.set(key, {
value,
expires: Date.now() + ttl,
accessCount: 0,
lastAccess: Date.now(),
priority
});
}
// 获取缓存
get(key) {
const item = this.cache.get(key);
if (!item) return undefined;
// 检查过期
if (Date.now() > item.expires) {
this.cache.delete(key);
return undefined;
}
// 更新访问信息
item.accessCount++;
item.lastAccess = Date.now();
return item.value;
}
// 驱逐策略
evict() {
let keyToEvict;
switch (this.strategy) {
case 'lru':
keyToEvict = this.findLRU();
break;
case 'lfu':
keyToEvict = this.findLFU();
break;
case 'fifo':
keyToEvict = this.cache.keys().next().value;
break;
}
if (keyToEvict) {
this.cache.delete(keyToEvict);
this.stats.evictions++;
}
}
findLRU() {
let oldest = null;
let oldestTime = Infinity;
for (const [key, item] of this.cache) {
if (item.lastAccess < oldestTime && item.priority === 0) {
oldest = key;
oldestTime = item.lastAccess;
}
}
return oldest;
}
findLFU() {
let leastUsed = null;
let minCount = Infinity;
for (const [key, item] of this.cache) {
if (item.accessCount < minCount && item.priority === 0) {
leastUsed = key;
minCount = item.accessCount;
}
}
return leastUsed;
}
// 清理过期项
cleanup() {
const now = Date.now();
for (const [key, item] of this.cache) {
if (now > item.expires) {
this.cache.delete(key);
}
}
}
// 获取统计信息
getStats() {
const hitRate = this.stats.hits / (this.stats.hits + this.stats.misses) || 0;
return {
...this.stats,
hitRate: hitRate.toFixed(2),
size: this.cache.size,
maxSize: this.maxSize
};
}
}
// 记忆化装饰器
function memoize(fn, options = {}) {
const cache = new SmartCache(options);
return async function(...args) {
const key = JSON.stringify(args);
return cache.getOrCompute(key, () => fn.apply(this, args));
};
}
// 使用示例
class DataService {
constructor() {
this.cache = new SmartCache({
maxSize: 500,
ttl: 300000, // 5分钟
strategy: 'lru'
});
// 记忆化方法
this.calculateExpensive = memoize(
this._calculateExpensive.bind(this),
{ ttl: 60000 }
);
}
async getUserData(userId) {
return this.cache.getOrCompute(
`user:${userId}`,
async () => {
const response = await $http.get(`/api/users/${userId}`);
return response.data;
},
{ priority: 1 } // 高优先级,不易被驱逐
);
}
async _calculateExpensive(input) {
// 模拟复杂计算
await new Promise(resolve => setTimeout(resolve, 1000));
return input * 2;
}
}
五、错误处理和恢复机制
1. 组件错误边界
防止单个组件错误影响整个系统:
class ComponentErrorBoundary {
constructor(options = {}) {
this.errorHandlers = new Map();
this.globalHandler = options.globalHandler;
this.maxRetries = options.maxRetries || 3;
this.retryDelay = options.retryDelay || 1000;
this.errorLog = [];
}
// 包装组件方法
wrapComponent(component) {
const wrapped = Object.create(component);
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(component))
.filter(name => typeof component[name] === 'function' && name !== 'constructor');
methods.forEach(method => {
wrapped[method] = this.wrapMethod(component, method, component[method]);
});
return wrapped;
}
// 包装方法
wrapMethod(component, methodName, originalMethod) {
return async (...args) => {
const context = {
component: component.constructor.name,
method: methodName,
args,
retries: 0
};
while (context.retries <= this.maxRetries) {
try {
return await originalMethod.apply(component, args);
} catch (error) {
context.error = error;
context.retries++;
// 记录错误
this.logError(context);
// 调用错误处理器
const handled = await this.handleError(context);
if (handled === 'retry' && context.retries <= this.maxRetries) {
await new Promise(resolve =>
setTimeout(resolve, this.retryDelay * context.retries)
);
continue;
} else if (handled === 'fallback') {
return this.getFallbackValue(context);
} else if (handled === 'ignore') {
return undefined;
} else {
throw error;
}
}
}
throw new Error(`Max retries exceeded for ${context.component}.${context.method}`);
};
}
// 处理错误
async handleError(context) {
// 组件特定的错误处理器
const componentHandler = this.errorHandlers.get(context.component);
if (componentHandler) {
const result = await componentHandler(context);
if (result) return result;
}
// 全局错误处理器
if (this.globalHandler) {
return await this.globalHandler(context);
}
// 默认处理
return this.defaultErrorHandler(context);
}
// 默认错误处理器
defaultErrorHandler(context) {
const { error } = context;
// 网络错误:重试
if (error.message?.includes('network') || error.code === 'ECONNREFUSED') {
return 'retry';
}
// 数据错误:使用降级值
if (error.message?.includes('parse') || error.name === 'SyntaxError') {
return 'fallback';
}
// 其他错误:抛出
return 'throw';
}
// 注册组件错误处理器
registerHandler(componentName, handler) {
this.errorHandlers.set(componentName, handler);
}
// 记录错误
logError(context) {
const errorInfo = {
timestamp: Date.now(),
component: context.component,
method: context.method,
error: {
name: context.error.name,
message: context.error.message,
stack: context.error.stack
},
retries: context.retries
};
this.errorLog.push(errorInfo);
// 限制日志大小
if (this.errorLog.length > 1000) {
this.errorLog = this.errorLog.slice(-500);
}
// 发送错误报告
this.reportError(errorInfo);
}
// 获取降级值
getFallbackValue(context) {
// 根据方法名返回合适的降级值
if (context.method.startsWith('get')) {
return null;
} else if (context.method.startsWith('is')) {
return false;
} else if (context.method.includes('List') || context.method.includes('Array')) {
return [];
} else {
return undefined;
}
}
// 错误报告
async reportError(errorInfo) {
// 批量发送错误报告
if (!this.reportQueue) {
this.reportQueue = [];
}
this.reportQueue.push(errorInfo);
if (!this.reportTimer) {
this.reportTimer = setTimeout(() => {
this.sendErrorReports();
this.reportTimer = null;
}, 5000);
}
}
async sendErrorReports() {
if (this.reportQueue.length === 0) return;
try {
await $http.post({
url: '/api/errors',
body: {
errors: this.reportQueue,
device: $device.info,
app: {
version: $app.info.version,
build: $app.info.build
}
}
});
this.reportQueue = [];
} catch (error) {
console.error('Failed to send error reports:', error);
}
}
}
// 使用示例
const errorBoundary = new ComponentErrorBoundary({
maxRetries: 3,
retryDelay: 1000,
globalHandler: async (context) => {
// 显示错误提示
$ui.toast(`操作失败: ${context.error.message}`);
// 根据错误类型决定处理方式
if (context.error.code === 401) {
// 认证错误,重新登录
await reLogin();
return 'retry';
}
return null;
}
});
// 注册特定组件的错误处理
errorBoundary.registerHandler('DataFetcher', async (context) => {
if (context.method === 'fetchUserData') {
// 使用缓存数据
const cachedData = await getCachedUserData();
if (cachedData) {
return 'fallback';
}
}
return null;
});
// 包装组件
const safeComponent = errorBoundary.wrapComponent(new DataFetcher());
2. 状态恢复机制
实现组件状态的保存和恢复:
class StateRecoveryManager {
constructor(options = {}) {
this.storage = options.storage || 'icloud'; // icloud, local, memory
this.autoSaveInterval = options.autoSaveInterval || 30000; // 30秒
this.maxSnapshots = options.maxSnapshots || 10;
this.components = new Map();
}
// 注册组件
registerComponent(id, component) {
const recovery = {
id,
component,
snapshots: [],
lastSave: 0,
dirty: false
};
this.components.set(id, recovery);
// 注入恢复方法
component.recovery = {
markDirty: () => this.markDirty(id),
save: () => this.saveComponent(id),
restore: (snapshotId) => this.restoreComponent(id, snapshotId),
getSnapshots: () => this.getSnapshots(id)
};
// 启动自动保存
if (this.autoSaveInterval > 0) {
this.startAutoSave(id);
}
}
// 标记为需要保存
markDirty(id) {
const recovery = this.components.get(id);
if (recovery) {
recovery.dirty = true;
}
}
// 保存组件状态
async saveComponent(id) {
const recovery = this.components.get(id);
if (!recovery || !recovery.dirty) return;
try {
// 获取组件状态
const state = await this.extractState(recovery.component);
// 创建快照
const snapshot = {
id: `${id}_${Date.now()}`,
componentId: id,
state,
timestamp: Date.now(),
metadata: {
version: recovery.component.version || '1.0.0',
size: JSON.stringify(state).length
}
};
// 添加到快照列表
recovery.snapshots.push(snapshot);
// 限制快照数量
if (recovery.snapshots.length > this.maxSnapshots) {
recovery.snapshots = recovery.snapshots.slice(-this.maxSnapshots);
}
// 持久化保存
await this.persistSnapshot(snapshot);
recovery.dirty = false;
recovery.lastSave = Date.now();
return snapshot;
} catch (error) {
console.error(`Failed to save component ${id}:`, error);
throw error;
}
}
// 提取组件状态
async extractState(component) {
if (component.getState) {
// 组件提供了获取状态的方法
return await component.getState();
} else {
// 自动提取可序列化的属性
const state = {};
for (const key in component) {
const value = component[key];
if (this.isSerializable(value)) {
state[key] = this.cloneValue(value);
}
}
return state;
}
}
// 恢复组件状态
async restoreComponent(id, snapshotId) {
const recovery = this.components.get(id);
if (!recovery) throw new Error(`Component ${id} not registered`);
let snapshot;
if (snapshotId) {
// 恢复特定快照
snapshot = recovery.snapshots.find(s => s.id === snapshotId);
} else {
// 恢复最新快照
snapshot = recovery.snapshots[recovery.snapshots.length - 1];
}
if (!snapshot) {
// 从持久化存储加载
snapshot = await this.loadSnapshot(id, snapshotId);
}
if (!snapshot) {
throw new Error(`No snapshot found for component ${id}`);
}
// 恢复状态
if (recovery.component.setState) {
await recovery.component.setState(snapshot.state);
} else {
// 直接赋值
Object.assign(recovery.component, snapshot.state);
}
// 触发恢复事件
if (recovery.component.onRestore) {
await recovery.component.onRestore(snapshot);
}
return snapshot;
}
// 持久化快照
async persistSnapshot(snapshot) {
const key = `recovery_${snapshot.componentId}_${snapshot.id}`;
switch (this.storage) {
case 'icloud':
$cloud.put({
key,
value: snapshot
});
break;
case 'local':
$cache.set(key, snapshot);
break;
case 'memory':
// 已经在内存中
break;
}
}
// 加载快照
async loadSnapshot(componentId, snapshotId) {
const key = snapshotId ?
`recovery_${componentId}_${snapshotId}` :
`recovery_${componentId}_latest`;
switch (this.storage) {
case 'icloud':
return await $cloud.get(key);
case 'local':
return $cache.get(key);
default:
return null;
}
}
// 启动自动保存
startAutoSave(id) {
const timer = setInterval(() => {
const recovery = this.components.get(id);
if (recovery && recovery.dirty) {
this.saveComponent(id).catch(error => {
console.error(`Auto-save failed for ${id}:`, error);
});
}
}, this.autoSaveInterval);
// 保存定时器引用以便清理
if (!this.timers) this.timers = new Map();
this.timers.set(id, timer);
}
// 判断是否可序列化
isSerializable(value) {
if (value === null || value === undefined) return true;
const type = typeof value;
if (type === 'string' || type === 'number' || type === 'boolean') return true;
if (value instanceof Date) return true;
if (Array.isArray(value)) {
return value.every(item => this.isSerializable(item));
}
if (type === 'object') {
// 排除函数和特殊对象
if (value.constructor && value.constructor !== Object) return false;
return Object.values(value).every(v => this.isSerializable(v));
}
return false;
}
// 深度克隆值
cloneValue(value) {
if (value === null || value === undefined) return value;
if (value instanceof Date) return new Date(value);
if (Array.isArray(value)) {
return value.map(item => this.cloneValue(item));
}
if (typeof value === 'object') {
const cloned = {};
for (const key in value) {
cloned[key] = this.cloneValue(value[key]);
}
return cloned;
}
return value;
}
// 清理
cleanup() {
// 保存所有脏组件
for (const [id, recovery] of this.components) {
if (recovery.dirty) {
this.saveComponent(id);
}
}
// 清理定时器
if (this.timers) {
for (const timer of this.timers.values()) {
clearInterval(timer);
}
}
}
}
// 使用示例
const recoveryManager = new StateRecoveryManager({
storage: 'icloud',
autoSaveInterval: 30000,
maxSnapshots: 5
});
// 可恢复的组件
class RecoverableEditor {
constructor() {
this.content = '';
this.cursorPosition = 0;
this.history = [];
recoveryManager.registerComponent('editor', this);
}
updateContent(newContent) {
this.content = newContent;
this.history.push({
content: newContent,
timestamp: Date.now()
});
// 标记需要保存
this.recovery.markDirty();
}
async getState() {
return {
content: this.content,
cursorPosition: this.cursorPosition,
history: this.history.slice(-10) // 只保存最近10条历史
};
}
async setState(state) {
this.content = state.content || '';
this.cursorPosition = state.cursorPosition || 0;
this.history = state.history || [];
// 更新UI
this.render();
}
async onRestore(snapshot) {
$ui.toast(`已恢复到 ${new Date(snapshot.timestamp).toLocaleString()}`);
}
}
六、最佳实践总结
1. 架构设计原则
// 1. 单一职责原则
class MessageComponent {
// 只负责消息显示
displayMessage(message) { /* ... */ }
}
class MessageValidator {
// 只负责消息验证
validate(message) { /* ... */ }
}
// 2. 依赖倒置原则
class Component {
constructor(eventBus) {
// 依赖抽象而不是具体实现
this.eventBus = eventBus;
}
}
// 3. 开闭原则
class ExtensibleComponent {
constructor() {
this.plugins = [];
}
use(plugin) {
this.plugins.push(plugin);
plugin.install(this);
}
}
2. 性能优化清单
// 性能监控工具
class PerformanceMonitor {
measure(name, fn) {
const start = performance.now();
const result = fn();
const duration = performance.now() - start;
if (duration > 16) { // 超过一帧
console.warn(`Slow operation ${name}: ${duration}ms`);
}
return result;
}
}
// 使用示例
const monitor = new PerformanceMonitor();
monitor.measure('render', () => {
component.render();
});
3. 调试和测试
// 组件测试框架
class ComponentTester {
constructor(component) {
this.component = component;
this.eventLog = [];
this.stateHistory = [];
this.setupLogging();
}
setupLogging() {
// 拦截事件
const originalEmit = this.component.emit;
this.component.emit = (event, data) => {
this.eventLog.push({ event, data, timestamp: Date.now() });
return originalEmit.call(this.component, event, data);
};
// 拦截状态变化
const originalSetState = this.component.setState;
this.component.setState = (state) => {
this.stateHistory.push({
before: { ...this.component.state },
after: { ...this.component.state, ...state },
timestamp: Date.now()
});
return originalSetState.call(this.component, state);
};
}
async simulate(scenario) {
console.log(`Running scenario: ${scenario.name}`);
for (const step of scenario.steps) {
await this.executeStep(step);
}
return this.generateReport();
}
async executeStep(step) {
switch (step.type) {
case 'event':
this.component.handleEvent(step.event, step.data);
break;
case 'state':
this.component.setState(step.state);
break;
case 'wait':
await new Promise(resolve => setTimeout(resolve, step.duration));
break;
case 'assert':
const actual = step.getter(this.component);
if (actual !== step.expected) {
throw new Error(`Assertion failed: expected ${step.expected}, got ${actual}`);
}
break;
}
}
generateReport() {
return {
events: this.eventLog,
states: this.stateHistory,
finalState: this.component.state
};
}
}
结语
处理组件间的复杂交互和数据同步是构建大型 JSBox 应用的核心挑战。通过合理的架构设计,我们可以构建出高效、可靠、可维护的系统。
关键要点:
- 选择合适的通信模式:根据具体场景选择中介者、数据流、状态同步等模式
- 保证数据一致性:使用事务、CRDT 等技术确保多组件数据同步
- 优化性能:通过批处理、缓存、虚拟化等技术提升响应速度
- 完善错误处理:建立错误边界和恢复机制,提高系统稳定性
- 便于调试维护:提供完善的日志、监控和测试工具
记住,好的架构不是一蹴而就的,需要在实践中不断迭代和优化。根据应用的具体需求和约束条件,灵活运用这些模式和技术,才能构建出真正优秀的 JSBox 应用。